mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-24 15:10:44 +01:00
Refactor wallets, add support for both wallet seeds (restore still not working). Cleanups.
This commit is contained in:
parent
38a69c7711
commit
a218bd1e15
67 changed files with 929 additions and 863 deletions
|
@ -23,10 +23,10 @@ import io.bitsquare.app.Log;
|
|||
import io.bitsquare.arbitration.messages.*;
|
||||
import io.bitsquare.arbitration.payload.Attachment;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.exceptions.TransactionVerificationException;
|
||||
import io.bitsquare.btc.exceptions.WalletException;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.TradeWalletService;
|
||||
import io.bitsquare.common.Timer;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.crypto.KeyRing;
|
||||
|
@ -71,7 +71,7 @@ public class DisputeManager {
|
|||
private final TradeWalletService tradeWalletService;
|
||||
private final BtcWalletService walletService;
|
||||
private final TradeManager tradeManager;
|
||||
private ClosedTradableManager closedTradableManager;
|
||||
private final ClosedTradableManager closedTradableManager;
|
||||
private final OpenOfferManager openOfferManager;
|
||||
private final P2PService p2PService;
|
||||
private final KeyRing keyRing;
|
||||
|
@ -83,7 +83,7 @@ public class DisputeManager {
|
|||
private final CopyOnWriteArraySet<DecryptedMsgWithPubKey> decryptedDirectMessageWithPubKeys = new CopyOnWriteArraySet<>();
|
||||
private final Map<String, Dispute> openDisputes;
|
||||
private final Map<String, Dispute> closedDisputes;
|
||||
private Map<String, Timer> delayMsgMap = new HashMap<>();
|
||||
private final Map<String, Timer> delayMsgMap = new HashMap<>();
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -91,14 +91,14 @@ public class DisputeManager {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public DisputeManager(P2PService p2PService,
|
||||
TradeWalletService tradeWalletService,
|
||||
BtcWalletService walletService,
|
||||
TradeManager tradeManager,
|
||||
ClosedTradableManager closedTradableManager,
|
||||
OpenOfferManager openOfferManager,
|
||||
KeyRing keyRing,
|
||||
@Named(Storage.DIR_KEY) File storageDir) {
|
||||
private DisputeManager(P2PService p2PService,
|
||||
TradeWalletService tradeWalletService,
|
||||
BtcWalletService walletService,
|
||||
TradeManager tradeManager,
|
||||
ClosedTradableManager closedTradableManager,
|
||||
OpenOfferManager openOfferManager,
|
||||
KeyRing keyRing,
|
||||
@Named(Storage.DIR_KEY) File storageDir) {
|
||||
this.p2PService = p2PService;
|
||||
this.tradeWalletService = tradeWalletService;
|
||||
this.walletService = walletService;
|
||||
|
|
|
@ -23,6 +23,10 @@ import io.bitsquare.app.AppOptionKeys;
|
|||
import io.bitsquare.btc.blockchain.BlockchainService;
|
||||
import io.bitsquare.btc.provider.fee.FeeService;
|
||||
import io.bitsquare.btc.provider.price.PriceFeedService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.SquWalletService;
|
||||
import io.bitsquare.btc.wallet.TradeWalletService;
|
||||
import io.bitsquare.btc.wallet.WalletsSetup;
|
||||
import io.bitsquare.http.HttpClient;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -56,7 +60,7 @@ public class BitcoinModule extends AppModule {
|
|||
bindConstant().annotatedWith(named(AppOptionKeys.PROVIDERS)).to(env.getRequiredProperty(AppOptionKeys.PROVIDERS));
|
||||
|
||||
bind(AddressEntryList.class).in(Singleton.class);
|
||||
bind(WalletSetup.class).in(Singleton.class);
|
||||
bind(WalletsSetup.class).in(Singleton.class);
|
||||
bind(BtcWalletService.class).in(Singleton.class);
|
||||
bind(SquWalletService.class).in(Singleton.class);
|
||||
bind(TradeWalletService.class).in(Singleton.class);
|
||||
|
|
|
@ -15,12 +15,11 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.bitcoinj.crypto.ChildNumber;
|
||||
import org.bitcoinj.crypto.DeterministicKey;
|
||||
import org.bitcoinj.crypto.HDUtils;
|
||||
import org.bitcoinj.crypto.KeyCrypter;
|
||||
import org.bitcoinj.wallet.DeterministicKeyChain;
|
||||
import org.bitcoinj.wallet.DeterministicSeed;
|
||||
|
@ -29,13 +28,13 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public class BitcoinDeterministicKeyChain extends DeterministicKeyChain {
|
||||
class BitcoinDeterministicKeyChain extends DeterministicKeyChain {
|
||||
private static final Logger log = LoggerFactory.getLogger(BitcoinDeterministicKeyChain.class);
|
||||
|
||||
// See https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
|
||||
// https://github.com/satoshilabs/slips/blob/master/slip-0044.md
|
||||
// We use 0 (0x80000000) as coin_type for BTC
|
||||
public static ImmutableList<ChildNumber> BIP44_BTC_ACCOUNT_PATH = ImmutableList.of(
|
||||
public static final ImmutableList<ChildNumber> BIP44_BTC_ACCOUNT_PATH = ImmutableList.of(
|
||||
new ChildNumber(44, true),
|
||||
new ChildNumber(0, true),
|
||||
ChildNumber.ZERO_HARDENED,
|
||||
|
@ -55,8 +54,6 @@ public class BitcoinDeterministicKeyChain extends DeterministicKeyChain {
|
|||
|
||||
@Override
|
||||
protected ImmutableList<ChildNumber> getAccountPath() {
|
||||
log.error(HDUtils.formatPath(BIP44_BTC_ACCOUNT_PATH));
|
||||
|
||||
return BIP44_BTC_ACCOUNT_PATH;
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.bitcoinj.crypto.ChildNumber;
|
||||
|
@ -28,8 +28,8 @@ import org.bitcoinj.wallet.DeterministicSeed;
|
|||
import org.bitcoinj.wallet.KeyChainFactory;
|
||||
import org.bitcoinj.wallet.Protos;
|
||||
|
||||
public class BitsquareKeyChainFactory implements KeyChainFactory {
|
||||
private boolean useBitcoinDeterministicKeyChain;
|
||||
class BitsquareKeyChainFactory implements KeyChainFactory {
|
||||
private final boolean useBitcoinDeterministicKeyChain;
|
||||
|
||||
public BitsquareKeyChainFactory(boolean useBitcoinDeterministicKeyChain) {
|
||||
this.useBitcoinDeterministicKeyChain = useBitcoinDeterministicKeyChain;
|
|
@ -15,7 +15,7 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
import org.bitcoinj.wallet.DeterministicKeyChain;
|
||||
|
@ -24,8 +24,8 @@ import org.bitcoinj.wallet.KeyChainGroup;
|
|||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public class BitsquareKeyChainGroup extends KeyChainGroup {
|
||||
private boolean useBitcoinDeterministicKeyChain;
|
||||
class BitsquareKeyChainGroup extends KeyChainGroup {
|
||||
private final boolean useBitcoinDeterministicKeyChain;
|
||||
|
||||
public boolean isUseBitcoinDeterministicKeyChain() {
|
||||
return useBitcoinDeterministicKeyChain;
|
||||
|
@ -36,8 +36,8 @@ public class BitsquareKeyChainGroup extends KeyChainGroup {
|
|||
this.useBitcoinDeterministicKeyChain = useBitcoinDeterministicKeyChain;
|
||||
}
|
||||
|
||||
public BitsquareKeyChainGroup(NetworkParameters params, DeterministicSeed watchKey, boolean useBitcoinDeterministicKeyChain) {
|
||||
super(params, watchKey);
|
||||
public BitsquareKeyChainGroup(NetworkParameters params, DeterministicSeed seed, boolean useBitcoinDeterministicKeyChain) {
|
||||
super(params, seed);
|
||||
this.useBitcoinDeterministicKeyChain = useBitcoinDeterministicKeyChain;
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.bitcoinj.core.*;
|
||||
|
@ -36,16 +36,16 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
* We use a specialized version of the CoinSelector based on the DefaultCoinSelector implementation.
|
||||
* We lookup for spendable outputs which matches our address of our addressEntry.
|
||||
*/
|
||||
abstract class BitsquareCoinSelector implements CoinSelector {
|
||||
private static final Logger log = LoggerFactory.getLogger(BitsquareCoinSelector.class);
|
||||
protected final NetworkParameters params;
|
||||
abstract class BtcCoinSelector implements CoinSelector {
|
||||
private static final Logger log = LoggerFactory.getLogger(BtcCoinSelector.class);
|
||||
final NetworkParameters params;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected BitsquareCoinSelector(NetworkParameters params) {
|
||||
BtcCoinSelector(NetworkParameters params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ abstract class BitsquareCoinSelector implements CoinSelector {
|
|||
/**
|
||||
* Sub-classes can override this to just customize whether transactions are usable, but keep age sorting.
|
||||
*/
|
||||
protected boolean shouldSelect(Transaction tx) {
|
||||
private boolean shouldSelect(Transaction tx) {
|
||||
return isInBlockChainOrPending(tx);
|
||||
}
|
||||
|
|
@ -15,24 +15,21 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import io.bitsquare.btc.exceptions.SigningException;
|
||||
import io.bitsquare.btc.*;
|
||||
import io.bitsquare.btc.exceptions.TransactionVerificationException;
|
||||
import io.bitsquare.btc.exceptions.WalletException;
|
||||
import io.bitsquare.btc.provider.fee.FeeService;
|
||||
import io.bitsquare.common.handlers.ErrorMessageHandler;
|
||||
import io.bitsquare.common.handlers.ExceptionHandler;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
import io.bitsquare.user.Preferences;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.crypto.DeterministicKey;
|
||||
import org.bitcoinj.crypto.KeyCrypterScrypt;
|
||||
import org.bitcoinj.wallet.DeterministicSeed;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -63,55 +60,43 @@ public class BtcWalletService extends WalletService {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public BtcWalletService(WalletSetup walletSetup,
|
||||
public BtcWalletService(WalletsSetup walletsSetup,
|
||||
AddressEntryList addressEntryList,
|
||||
Preferences preferences,
|
||||
FeeService feeService) {
|
||||
super(walletSetup,
|
||||
super(walletsSetup,
|
||||
preferences,
|
||||
feeService);
|
||||
|
||||
this.addressEntryList = addressEntryList;
|
||||
|
||||
walletSetup.addSetupCompletedHandler(() -> {
|
||||
wallet = walletSetup.getWallet();
|
||||
walletsSetup.addSetupCompletedHandler(() -> {
|
||||
wallet = walletsSetup.getBtcWallet();
|
||||
wallet.addEventListener(walletEventListener);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public Methods
|
||||
// Overridden Methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
void decryptWallet(@NotNull KeyParameter key) {
|
||||
super.decryptWallet(key);
|
||||
|
||||
public String exportWalletData(boolean includePrivKeys) {
|
||||
StringBuilder addressEntryListData = new StringBuilder();
|
||||
getAddressEntryListAsImmutableList().stream().forEach(e -> addressEntryListData.append(e.toString()).append("\n"));
|
||||
return "BitcoinJ wallet:\n" +
|
||||
wallet.toString(includePrivKeys, true, true, walletSetup.chain()) + "\n\n" +
|
||||
"Bitsquare address entry list:\n" +
|
||||
addressEntryListData.toString() +
|
||||
"All pubkeys as hex:\n" +
|
||||
wallet.printAllPubKeysAsHex();
|
||||
}
|
||||
|
||||
// TODO
|
||||
public void restoreSeedWords(DeterministicSeed seed, ResultHandler resultHandler, ExceptionHandler exceptionHandler) {
|
||||
walletSetup.restoreBtcSeedWords(seed, resultHandler, exceptionHandler);
|
||||
}
|
||||
|
||||
public void decryptWallet(@NotNull KeyParameter key) {
|
||||
addressEntryList.stream().forEach(e -> {
|
||||
final DeterministicKey keyPair = e.getKeyPair();
|
||||
if (keyPair != null && keyPair.isEncrypted())
|
||||
e.setDeterministicKey(keyPair.decrypt(key));
|
||||
});
|
||||
|
||||
addressEntryList.queueUpForSave();
|
||||
}
|
||||
|
||||
public void encryptWallet(KeyCrypterScrypt keyCrypterScrypt, KeyParameter key) {
|
||||
@Override
|
||||
void encryptWallet(KeyCrypterScrypt keyCrypterScrypt, KeyParameter key) {
|
||||
super.encryptWallet(keyCrypterScrypt, key);
|
||||
|
||||
addressEntryList.stream().forEach(e -> {
|
||||
final DeterministicKey keyPair = e.getKeyPair();
|
||||
if (keyPair != null && keyPair.isEncrypted())
|
||||
|
@ -120,13 +105,31 @@ public class BtcWalletService extends WalletService {
|
|||
addressEntryList.queueUpForSave();
|
||||
}
|
||||
|
||||
@Override
|
||||
String getWalletAsString(boolean includePrivKeys) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
getAddressEntryListAsImmutableList().stream().forEach(e -> sb.append(e.toString()).append("\n"));
|
||||
return "BitcoinJ wallet:\n" +
|
||||
wallet.toString(includePrivKeys, true, true, walletsSetup.getChain()) + "\n\n" +
|
||||
"Bitsquare address entry list:\n" +
|
||||
sb.toString() +
|
||||
"All pubkeys as hex:\n" +
|
||||
wallet.printAllPubKeysAsHex();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Fee tx for SQU
|
||||
// Public Methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Transaction getTransactionWithFeeInput(Transaction transaction) throws
|
||||
TransactionVerificationException, WalletException, AddressFormatException, AddressEntryException, InsufficientFundsException, SigningException {
|
||||
log.trace("takerCreatesDepositsTxInputs called");
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Add fee input to prepared SQU send tx
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Transaction addFeeInputToPreparedSquSendTx(Transaction transaction) throws
|
||||
TransactionVerificationException, WalletException, InsufficientFundsException {
|
||||
log.trace("addFeeInputToPreparedSquSendTx called");
|
||||
try {
|
||||
int counter = 0;
|
||||
int txSize = 407; // typical size for a tx with 2 inputs and 3 outputs
|
||||
|
@ -135,7 +138,7 @@ public class BtcWalletService extends WalletService {
|
|||
Address changeAddress = getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress();
|
||||
checkNotNull(feePaymentAddress, "feePaymentAddress must not be null");
|
||||
checkNotNull(changeAddress, "changeAddress must not be null");
|
||||
TokenFeeCoinSelector coinSelector = new TokenFeeCoinSelector(params, feePaymentAddress);
|
||||
SquCoinSelector coinSelector = new SquCoinSelector(params, feePaymentAddress);
|
||||
List<TransactionInput> inputs = transaction.getInputs();
|
||||
List<TransactionOutput> outputs = transaction.getOutputs();
|
||||
Transaction resultTx;
|
||||
|
@ -146,7 +149,7 @@ public class BtcWalletService extends WalletService {
|
|||
outputs.stream().forEach(tx::addOutput);
|
||||
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx);
|
||||
sendRequest.shuffleOutputs = false;
|
||||
sendRequest.aesKey = walletSetup.getAesKey();
|
||||
sendRequest.aesKey = aesKey;
|
||||
// Need to be false as it would try to sign all inputs (SQU inputs are not in this wallet)
|
||||
sendRequest.signInputs = false;
|
||||
sendRequest.ensureMinRequiredFee = false;
|
||||
|
@ -182,10 +185,6 @@ public class BtcWalletService extends WalletService {
|
|||
}
|
||||
}
|
||||
|
||||
public void commitTx(Transaction tx) {
|
||||
wallet.commitTx(tx);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// AddressEntry
|
||||
|
@ -223,7 +222,7 @@ public class BtcWalletService extends WalletService {
|
|||
return addressEntryList.addAddressEntry(new AddressEntry(wallet.freshReceiveKey(), wallet.getParams(), context));
|
||||
}
|
||||
|
||||
public Optional<AddressEntry> findAddressEntry(String address, AddressEntry.Context context) {
|
||||
private Optional<AddressEntry> findAddressEntry(String address, AddressEntry.Context context) {
|
||||
return getAddressEntryListAsImmutableList().stream()
|
||||
.filter(e -> address.equals(e.getAddressString()))
|
||||
.filter(e -> context == e.getContext())
|
||||
|
@ -248,7 +247,7 @@ public class BtcWalletService extends WalletService {
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<AddressEntry> getAddressEntryListAsImmutableList() {
|
||||
private List<AddressEntry> getAddressEntryListAsImmutableList() {
|
||||
return ImmutableList.copyOf(addressEntryList);
|
||||
}
|
||||
|
||||
|
@ -288,7 +287,7 @@ public class BtcWalletService extends WalletService {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void doubleSpendTransaction(String txId, Runnable resultHandler, ErrorMessageHandler errorMessageHandler)
|
||||
throws InsufficientMoneyException, AddressFormatException, AddressEntryException, InsufficientFundsException {
|
||||
throws InsufficientFundsException {
|
||||
AddressEntry addressEntry = getOrCreateUnusedAddressEntry(AddressEntry.Context.AVAILABLE);
|
||||
checkNotNull(addressEntry.getAddress(), "addressEntry.getAddress() must not be null");
|
||||
Optional<Transaction> transactionOptional = wallet.getTransactions(true).stream()
|
||||
|
@ -352,7 +351,7 @@ public class BtcWalletService extends WalletService {
|
|||
sendRequest = Wallet.SendRequest.forTx(newTransaction);
|
||||
sendRequest.fee = fee;
|
||||
sendRequest.feePerKb = Coin.ZERO;
|
||||
sendRequest.aesKey = walletSetup.getAesKey();
|
||||
sendRequest.aesKey = aesKey;
|
||||
sendRequest.coinSelector = new TradeWalletCoinSelector(params, toAddress);
|
||||
sendRequest.changeAddress = toAddress;
|
||||
wallet.completeTx(sendRequest);
|
||||
|
@ -371,7 +370,7 @@ public class BtcWalletService extends WalletService {
|
|||
sendRequest = Wallet.SendRequest.forTx(newTransaction);
|
||||
sendRequest.fee = fee;
|
||||
sendRequest.feePerKb = Coin.ZERO;
|
||||
sendRequest.aesKey = walletSetup.getAesKey();
|
||||
sendRequest.aesKey = aesKey;
|
||||
sendRequest.coinSelector = new TradeWalletCoinSelector(params, toAddress);
|
||||
sendRequest.changeAddress = toAddress;
|
||||
sendResult = wallet.sendCoins(sendRequest);
|
||||
|
@ -386,7 +385,7 @@ public class BtcWalletService extends WalletService {
|
|||
sendRequest = Wallet.SendRequest.forTx(newTransaction);
|
||||
sendRequest.fee = fee;
|
||||
sendRequest.feePerKb = Coin.ZERO;
|
||||
sendRequest.aesKey = walletSetup.getAesKey();
|
||||
sendRequest.aesKey = aesKey;
|
||||
sendRequest.coinSelector = new TradeWalletCoinSelector(params, toAddress, false);
|
||||
sendRequest.changeAddress = toAddress;
|
||||
|
||||
|
@ -459,7 +458,7 @@ public class BtcWalletService extends WalletService {
|
|||
if (fee.compareTo(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE) < 0)
|
||||
fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||
|
||||
Wallet.SendRequest sendRequest = getSendRequest(fromAddress, toAddress, amount, fee, walletSetup.getAesKey(), context);
|
||||
Wallet.SendRequest sendRequest = getSendRequest(fromAddress, toAddress, amount, fee, aesKey, context);
|
||||
wallet.completeTx(sendRequest);
|
||||
tx = sendRequest.tx;
|
||||
txSize = tx.bitcoinSerialize().length;
|
||||
|
@ -509,7 +508,7 @@ public class BtcWalletService extends WalletService {
|
|||
fee = txFeeForWithdrawalPerByte.multiply(txSize);
|
||||
if (fee.compareTo(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE) < 0)
|
||||
fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||
Wallet.SendRequest sendRequest = getSendRequestForMultipleAddresses(fromAddresses, toAddress, amount, fee, null, walletSetup.getAesKey());
|
||||
Wallet.SendRequest sendRequest = getSendRequestForMultipleAddresses(fromAddresses, toAddress, amount, fee, null, aesKey);
|
||||
wallet.completeTx(sendRequest);
|
||||
tx = sendRequest.tx;
|
||||
txSize = tx.bitcoinSerialize().length;
|
||||
|
@ -564,13 +563,13 @@ public class BtcWalletService extends WalletService {
|
|||
return sendResult.tx.getHashAsString();
|
||||
}
|
||||
|
||||
protected Wallet.SendRequest getSendRequest(String fromAddress,
|
||||
String toAddress,
|
||||
Coin amount,
|
||||
Coin fee,
|
||||
@Nullable KeyParameter aesKey,
|
||||
AddressEntry.Context context) throws AddressFormatException,
|
||||
AddressEntryException, InsufficientMoneyException {
|
||||
private Wallet.SendRequest getSendRequest(String fromAddress,
|
||||
String toAddress,
|
||||
Coin amount,
|
||||
Coin fee,
|
||||
@Nullable KeyParameter aesKey,
|
||||
AddressEntry.Context context) throws AddressFormatException,
|
||||
AddressEntryException {
|
||||
Transaction tx = new Transaction(params);
|
||||
Preconditions.checkArgument(Restrictions.isAboveDust(amount, fee),
|
||||
"The amount is too low (dust limit).");
|
||||
|
@ -598,7 +597,7 @@ public class BtcWalletService extends WalletService {
|
|||
Coin fee,
|
||||
@Nullable String changeAddress,
|
||||
@Nullable KeyParameter aesKey) throws
|
||||
AddressFormatException, AddressEntryException, InsufficientMoneyException {
|
||||
AddressFormatException, AddressEntryException {
|
||||
Transaction tx = new Transaction(params);
|
||||
Preconditions.checkArgument(Restrictions.isAboveDust(amount),
|
||||
"The amount is too low (dust limit).");
|
|
@ -15,8 +15,9 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import org.bitcoinj.core.Address;
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
import org.bitcoinj.core.TransactionConfidence;
|
||||
|
@ -31,7 +32,7 @@ import java.util.Set;
|
|||
* We use a specialized version of the CoinSelector based on the DefaultCoinSelector implementation.
|
||||
* We lookup for spendable outputs which matches our address of our addressEntry.
|
||||
*/
|
||||
class MultiAddressesCoinSelector extends BitsquareCoinSelector {
|
||||
class MultiAddressesCoinSelector extends BtcCoinSelector {
|
||||
private static final Logger log = LoggerFactory.getLogger(MultiAddressesCoinSelector.class);
|
||||
private final Set<AddressEntry> addressEntries;
|
||||
private final boolean allowUnconfirmedSpend;
|
||||
|
@ -46,7 +47,7 @@ class MultiAddressesCoinSelector extends BitsquareCoinSelector {
|
|||
}
|
||||
|
||||
|
||||
public MultiAddressesCoinSelector(NetworkParameters params, @NotNull Set<AddressEntry> addressEntries, boolean allowUnconfirmedSpend) {
|
||||
private MultiAddressesCoinSelector(NetworkParameters params, @NotNull Set<AddressEntry> addressEntries, boolean allowUnconfirmedSpend) {
|
||||
super(params);
|
||||
this.addressEntries = addressEntries;
|
||||
this.allowUnconfirmedSpend = allowUnconfirmedSpend;
|
||||
|
@ -55,7 +56,7 @@ class MultiAddressesCoinSelector extends BitsquareCoinSelector {
|
|||
@Override
|
||||
protected boolean matchesRequirement(TransactionOutput transactionOutput) {
|
||||
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isPayToScriptHash()) {
|
||||
boolean confirmationCheck = allowUnconfirmedSpend || false;
|
||||
boolean confirmationCheck = allowUnconfirmedSpend;
|
||||
if (!allowUnconfirmedSpend && transactionOutput.getParentTransaction() != null &&
|
||||
transactionOutput.getParentTransaction().getConfidence() != null) {
|
||||
final TransactionConfidence.ConfidenceType confidenceType = transactionOutput.getParentTransaction().getConfidence().getConfidenceType();
|
|
@ -15,8 +15,9 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import org.bitcoinj.core.Address;
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
import org.bitcoinj.core.TransactionOutput;
|
||||
|
@ -32,7 +33,7 @@ import java.util.stream.Collectors;
|
|||
* We use a specialized version of the CoinSelector based on the DefaultCoinSelector implementation.
|
||||
* We lookup for spendable outputs which matches our address of our addressEntry.
|
||||
*/
|
||||
class SavingsWalletCoinSelector extends BitsquareCoinSelector {
|
||||
class SavingsWalletCoinSelector extends BtcCoinSelector {
|
||||
private static final Logger log = LoggerFactory.getLogger(SavingsWalletCoinSelector.class);
|
||||
|
||||
private final Set<Address> savingsWalletAddressSet;
|
|
@ -15,7 +15,7 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import org.bitcoinj.core.Address;
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
|
@ -29,21 +29,21 @@ import org.slf4j.LoggerFactory;
|
|||
* We use a specialized version of the CoinSelector based on the DefaultCoinSelector implementation.
|
||||
* We lookup for spendable outputs which matches our address of our address.
|
||||
*/
|
||||
class TokenFeeCoinSelector extends BitsquareCoinSelector {
|
||||
private static final Logger log = LoggerFactory.getLogger(TokenFeeCoinSelector.class);
|
||||
class SquCoinSelector extends BtcCoinSelector {
|
||||
private static final Logger log = LoggerFactory.getLogger(SquCoinSelector.class);
|
||||
private final Address address;
|
||||
private boolean allowUnconfirmedSpend;
|
||||
private final boolean allowUnconfirmedSpend;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public TokenFeeCoinSelector(NetworkParameters params, @NotNull Address address) {
|
||||
SquCoinSelector(NetworkParameters params, @NotNull Address address) {
|
||||
this(params, address, true);
|
||||
}
|
||||
|
||||
public TokenFeeCoinSelector(NetworkParameters params, @NotNull Address address, boolean allowUnconfirmedSpend) {
|
||||
private SquCoinSelector(NetworkParameters params, @NotNull Address address, boolean allowUnconfirmedSpend) {
|
||||
super(params);
|
||||
this.address = address;
|
||||
this.allowUnconfirmedSpend = allowUnconfirmedSpend;
|
||||
|
@ -52,7 +52,7 @@ class TokenFeeCoinSelector extends BitsquareCoinSelector {
|
|||
@Override
|
||||
protected boolean matchesRequirement(TransactionOutput transactionOutput) {
|
||||
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isPayToScriptHash()) {
|
||||
boolean confirmationCheck = allowUnconfirmedSpend || false;
|
||||
boolean confirmationCheck = allowUnconfirmedSpend;
|
||||
if (!allowUnconfirmedSpend && transactionOutput.getParentTransaction() != null &&
|
||||
transactionOutput.getParentTransaction().getConfidence() != null) {
|
||||
final TransactionConfidence.ConfidenceType confidenceType = transactionOutput.getParentTransaction().getConfidence().getConfidenceType();
|
|
@ -15,12 +15,11 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.bitcoinj.crypto.ChildNumber;
|
||||
import org.bitcoinj.crypto.DeterministicKey;
|
||||
import org.bitcoinj.crypto.HDUtils;
|
||||
import org.bitcoinj.crypto.KeyCrypter;
|
||||
import org.bitcoinj.wallet.DeterministicKeyChain;
|
||||
import org.bitcoinj.wallet.DeterministicSeed;
|
||||
|
@ -29,14 +28,14 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public class SquDeterministicKeyChain extends DeterministicKeyChain {
|
||||
class SquDeterministicKeyChain extends DeterministicKeyChain {
|
||||
private static final Logger log = LoggerFactory.getLogger(SquDeterministicKeyChain.class);
|
||||
|
||||
// See https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
|
||||
// https://github.com/satoshilabs/slips/blob/master/slip-0044.md
|
||||
// We use 139 (0x80000000) as coin_type for SQU
|
||||
// TODO register once the token name is fix
|
||||
public static ImmutableList<ChildNumber> BIP44_SQU_ACCOUNT_PATH = ImmutableList.of(
|
||||
public static final ImmutableList<ChildNumber> BIP44_SQU_ACCOUNT_PATH = ImmutableList.of(
|
||||
new ChildNumber(44, true),
|
||||
new ChildNumber(139, true),
|
||||
ChildNumber.ZERO_HARDENED,
|
||||
|
@ -56,8 +55,6 @@ public class SquDeterministicKeyChain extends DeterministicKeyChain {
|
|||
|
||||
@Override
|
||||
protected ImmutableList<ChildNumber> getAccountPath() {
|
||||
log.error(HDUtils.formatPath(BIP44_SQU_ACCOUNT_PATH));
|
||||
|
||||
return BIP44_SQU_ACCOUNT_PATH;
|
||||
}
|
||||
|
|
@ -15,20 +15,17 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import io.bitsquare.btc.Restrictions;
|
||||
import io.bitsquare.btc.exceptions.TransactionVerificationException;
|
||||
import io.bitsquare.btc.exceptions.WalletException;
|
||||
import io.bitsquare.btc.provider.fee.FeeService;
|
||||
import io.bitsquare.common.handlers.ExceptionHandler;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
import io.bitsquare.user.Preferences;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.wallet.DeterministicSeed;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -48,59 +45,46 @@ public class SquWalletService extends WalletService {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public SquWalletService(WalletSetup walletSetup,
|
||||
public SquWalletService(WalletsSetup walletsSetup,
|
||||
Preferences preferences,
|
||||
FeeService feeService) {
|
||||
super(walletSetup,
|
||||
super(walletsSetup,
|
||||
preferences,
|
||||
feeService);
|
||||
|
||||
walletSetup.addSetupCompletedHandler(() -> {
|
||||
wallet = walletSetup.getTokenWallet();
|
||||
walletsSetup.addSetupCompletedHandler(() -> {
|
||||
wallet = walletsSetup.getSquWallet();
|
||||
wallet.addEventListener(walletEventListener);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Overridden Methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
String getWalletAsString(boolean includePrivKeys) {
|
||||
return "BitcoinJ wallet:\n" +
|
||||
wallet.toString(includePrivKeys, true, true, walletsSetup.getChain()) + "\n\n" +
|
||||
"All pubkeys as hex:\n" +
|
||||
wallet.printAllPubKeysAsHex();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public Methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public String exportWalletData(boolean includePrivKeys) {
|
||||
StringBuilder addressEntryListData = new StringBuilder();
|
||||
return "BitcoinJ SQU wallet:\n" +
|
||||
wallet.toString(includePrivKeys, true, true, walletSetup.chain()) + "\n\n" +
|
||||
"SQU address entry list:\n" +
|
||||
addressEntryListData.toString() +
|
||||
"All pubkeys as hex:\n" +
|
||||
wallet.printAllPubKeysAsHex();
|
||||
}
|
||||
|
||||
//TODO
|
||||
public void restoreSeedWords(DeterministicSeed seed, ResultHandler resultHandler, ExceptionHandler exceptionHandler) {
|
||||
/* Context ctx = Context.get();
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Context.propagate(ctx);
|
||||
walletAppKit.stopAsync();
|
||||
walletAppKit.awaitTerminated();
|
||||
initialize(seed, resultHandler, exceptionHandler);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
log.error("Executing task failed. " + t.getMessage());
|
||||
}
|
||||
}, "RestoreWallet-%d").start();*/
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Withdrawal Send
|
||||
// Send SQU with BTC fee
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Transaction prepareSendTx(String receiverAddress,
|
||||
Coin receiverAmount,
|
||||
Optional<String> changeAddressStringOptional) throws AddressFormatException,
|
||||
AddressEntryException, InsufficientMoneyException, WalletException, TransactionVerificationException {
|
||||
public Transaction getPreparedSendTx(String receiverAddress,
|
||||
Coin receiverAmount,
|
||||
Optional<String> changeAddressStringOptional) throws AddressFormatException,
|
||||
InsufficientMoneyException, WalletException, TransactionVerificationException {
|
||||
|
||||
Transaction tx = new Transaction(params);
|
||||
Preconditions.checkArgument(Restrictions.isAboveDust(receiverAmount),
|
||||
|
@ -110,7 +94,7 @@ public class SquWalletService extends WalletService {
|
|||
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx);
|
||||
sendRequest.fee = Coin.ZERO;
|
||||
sendRequest.feePerKb = Coin.ZERO;
|
||||
sendRequest.aesKey = walletSetup.getAesKey();
|
||||
sendRequest.aesKey = aesKey;
|
||||
sendRequest.shuffleOutputs = false;
|
||||
sendRequest.signInputs = false;
|
||||
sendRequest.ensureMinRequiredFee = false;
|
||||
|
@ -124,7 +108,14 @@ public class SquWalletService extends WalletService {
|
|||
return tx;
|
||||
}
|
||||
|
||||
public Transaction signFinalSendTx(Transaction tx) throws WalletException, TransactionVerificationException {
|
||||
public void signAndBroadcastSendTx(Transaction tx, FutureCallback<Transaction> callback) throws WalletException, TransactionVerificationException {
|
||||
Transaction signedTx = signFinalSendTx(tx);
|
||||
wallet.commitTx(signedTx);
|
||||
Futures.addCallback(walletsSetup.getPeerGroup().broadcastTransaction(signedTx).future(), callback);
|
||||
printTx("commitAndBroadcastTx", signedTx);
|
||||
}
|
||||
|
||||
private Transaction signFinalSendTx(Transaction tx) throws WalletException, TransactionVerificationException {
|
||||
// TODO
|
||||
int index = 0;
|
||||
TransactionInput txIn = tx.getInput(index);
|
||||
|
@ -138,22 +129,4 @@ public class SquWalletService extends WalletService {
|
|||
return tx;
|
||||
}
|
||||
|
||||
public void commitAndBroadcastTx(Transaction tx, FutureCallback<Transaction> callback) {
|
||||
wallet.commitTx(tx);
|
||||
ListenableFuture<Transaction> broadcastComplete = walletSetup.peerGroup().broadcastTransaction(tx).future();
|
||||
Futures.addCallback(broadcastComplete, callback);
|
||||
printTx("commitAndBroadcastTx", tx);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Getters
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Util
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import org.bitcoinj.core.Address;
|
||||
import org.bitcoinj.core.NetworkParameters;
|
||||
|
@ -29,10 +29,10 @@ import org.slf4j.LoggerFactory;
|
|||
* We use a specialized version of the CoinSelector based on the DefaultCoinSelector implementation.
|
||||
* We lookup for spendable outputs which matches our address of our address.
|
||||
*/
|
||||
class TradeWalletCoinSelector extends BitsquareCoinSelector {
|
||||
class TradeWalletCoinSelector extends BtcCoinSelector {
|
||||
private static final Logger log = LoggerFactory.getLogger(TradeWalletCoinSelector.class);
|
||||
private final Address address;
|
||||
private boolean allowUnconfirmedSpend;
|
||||
private final boolean allowUnconfirmedSpend;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -52,7 +52,7 @@ class TradeWalletCoinSelector extends BitsquareCoinSelector {
|
|||
@Override
|
||||
protected boolean matchesRequirement(TransactionOutput transactionOutput) {
|
||||
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isPayToScriptHash()) {
|
||||
boolean confirmationCheck = allowUnconfirmedSpend || false;
|
||||
boolean confirmationCheck = allowUnconfirmedSpend;
|
||||
if (!allowUnconfirmedSpend && transactionOutput.getParentTransaction() != null &&
|
||||
transactionOutput.getParentTransaction().getConfidence() != null) {
|
||||
final TransactionConfidence.ConfidenceType confidenceType = transactionOutput.getParentTransaction().getConfidence().getConfidenceType();
|
|
@ -15,7 +15,7 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
@ -23,6 +23,8 @@ import com.google.common.util.concurrent.FutureCallback;
|
|||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import io.bitsquare.app.Log;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.AddressEntryList;
|
||||
import io.bitsquare.btc.data.InputsAndChangeOutput;
|
||||
import io.bitsquare.btc.data.PreparedDepositTxAndOffererInputs;
|
||||
import io.bitsquare.btc.data.RawTransactionInput;
|
||||
|
@ -97,7 +99,7 @@ public class TradeWalletService {
|
|||
@Nullable
|
||||
private Wallet wallet;
|
||||
@Nullable
|
||||
private BitSquareWalletAppKit walletAppKit;
|
||||
private WalletConfig walletConfig;
|
||||
@Nullable
|
||||
private KeyParameter aesKey;
|
||||
private AddressEntryList addressEntryList;
|
||||
|
@ -113,12 +115,12 @@ public class TradeWalletService {
|
|||
}
|
||||
|
||||
// After WalletService is initialized we get the walletAppKit set
|
||||
public void setWalletAppKit(BitSquareWalletAppKit walletAppKit) {
|
||||
this.walletAppKit = walletAppKit;
|
||||
wallet = walletAppKit.wallet();
|
||||
public void setWalletConfig(WalletConfig walletConfig) {
|
||||
this.walletConfig = walletConfig;
|
||||
wallet = walletConfig.wallet();
|
||||
}
|
||||
|
||||
public void setAesKey(KeyParameter aesKey) {
|
||||
void setAesKey(KeyParameter aesKey) {
|
||||
this.aesKey = aesKey;
|
||||
}
|
||||
|
||||
|
@ -194,7 +196,7 @@ public class TradeWalletService {
|
|||
* @throws WalletException
|
||||
*/
|
||||
public InputsAndChangeOutput takerCreatesDepositsTxInputs(Coin inputAmount, Coin txFee, AddressEntry takersAddressEntry, Address takersChangeAddress) throws
|
||||
TransactionVerificationException, WalletException, AddressFormatException {
|
||||
TransactionVerificationException, WalletException {
|
||||
log.trace("takerCreatesDepositsTxInputs called");
|
||||
log.trace("inputAmount " + inputAmount.toFriendlyString());
|
||||
log.trace("txFee " + txFee.toFriendlyString());
|
||||
|
@ -506,8 +508,8 @@ public class TradeWalletService {
|
|||
BtcWalletService.printTx("depositTx", depositTx);
|
||||
|
||||
// Broadcast depositTx
|
||||
checkNotNull(walletAppKit);
|
||||
ListenableFuture<Transaction> broadcastComplete = walletAppKit.peerGroup().broadcastTransaction(depositTx).future();
|
||||
checkNotNull(walletConfig);
|
||||
ListenableFuture<Transaction> broadcastComplete = walletConfig.peerGroup().broadcastTransaction(depositTx).future();
|
||||
Futures.addCallback(broadcastComplete, callback);
|
||||
|
||||
return depositTx;
|
||||
|
@ -947,8 +949,8 @@ public class TradeWalletService {
|
|||
verifyTransaction(payoutTx);
|
||||
checkWalletConsistency();
|
||||
|
||||
if (walletAppKit != null) {
|
||||
ListenableFuture<Transaction> future = walletAppKit.peerGroup().broadcastTransaction(payoutTx).future();
|
||||
if (walletConfig != null) {
|
||||
ListenableFuture<Transaction> future = walletConfig.peerGroup().broadcastTransaction(payoutTx).future();
|
||||
Futures.addCallback(future, callback);
|
||||
}
|
||||
|
||||
|
@ -965,8 +967,8 @@ public class TradeWalletService {
|
|||
* @param callback
|
||||
*/
|
||||
public void broadcastTx(Transaction tx, FutureCallback<Transaction> callback) {
|
||||
checkNotNull(walletAppKit);
|
||||
ListenableFuture<Transaction> future = walletAppKit.peerGroup().broadcastTransaction(tx).future();
|
||||
checkNotNull(walletConfig);
|
||||
ListenableFuture<Transaction> future = walletConfig.peerGroup().broadcastTransaction(tx).future();
|
||||
Futures.addCallback(future, callback);
|
||||
}
|
||||
|
||||
|
@ -1025,23 +1027,23 @@ public class TradeWalletService {
|
|||
}
|
||||
|
||||
public ListenableFuture<StoredBlock> getBlockHeightFuture(Transaction transaction) {
|
||||
checkNotNull(walletAppKit);
|
||||
return walletAppKit.chain().getHeightFuture((int) transaction.getLockTime());
|
||||
checkNotNull(walletConfig);
|
||||
return walletConfig.chain().getHeightFuture((int) transaction.getLockTime());
|
||||
}
|
||||
|
||||
public int getBestChainHeight() {
|
||||
checkNotNull(walletAppKit);
|
||||
return walletAppKit.chain().getBestChainHeight();
|
||||
checkNotNull(walletConfig);
|
||||
return walletConfig.chain().getBestChainHeight();
|
||||
}
|
||||
|
||||
public void addBlockChainListener(BlockChainListener blockChainListener) {
|
||||
checkNotNull(walletAppKit);
|
||||
walletAppKit.chain().addListener(blockChainListener);
|
||||
checkNotNull(walletConfig);
|
||||
walletConfig.chain().addListener(blockChainListener);
|
||||
}
|
||||
|
||||
public void removeBlockChainListener(BlockChainListener blockChainListener) {
|
||||
checkNotNull(walletAppKit);
|
||||
walletAppKit.chain().removeListener(blockChainListener);
|
||||
checkNotNull(walletConfig);
|
||||
walletConfig.chain().removeListener(blockChainListener);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1206,7 +1208,7 @@ public class TradeWalletService {
|
|||
this.addressEntryList = addressEntryList;
|
||||
}
|
||||
|
||||
public List<AddressEntry> getAddressEntryListAsImmutableList() {
|
||||
private List<AddressEntry> getAddressEntryListAsImmutableList() {
|
||||
return ImmutableList.copyOf(addressEntryList);
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.util.concurrent.AbstractIdleService;
|
||||
|
@ -23,6 +23,7 @@ import com.google.common.util.concurrent.FutureCallback;
|
|||
import com.google.common.util.concurrent.Futures;
|
||||
import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;
|
||||
import com.subgraph.orchid.TorClient;
|
||||
import io.bitsquare.btc.ProxySocketFactory;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.net.BlockingClientManager;
|
||||
import org.bitcoinj.net.discovery.DnsDiscovery;
|
||||
|
@ -35,6 +36,7 @@ import org.bitcoinj.store.WalletProtobufSerializer;
|
|||
import org.bitcoinj.wallet.DeterministicSeed;
|
||||
import org.bitcoinj.wallet.KeyChainGroup;
|
||||
import org.bitcoinj.wallet.Protos;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -52,39 +54,41 @@ import java.util.concurrent.TimeoutException;
|
|||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
public class BitSquareWalletAppKit extends AbstractIdleService {
|
||||
private static final Logger log = LoggerFactory.getLogger(BitSquareWalletAppKit.class);
|
||||
// Derived from WalletAppKit
|
||||
public class WalletConfig extends AbstractIdleService {
|
||||
private static final Logger log = LoggerFactory.getLogger(WalletConfig.class);
|
||||
|
||||
protected final String walletFilePrefix;
|
||||
protected final String tokenWalletFilePrefix;
|
||||
protected volatile Wallet vWallet;
|
||||
protected volatile Wallet vTokenWallet;
|
||||
protected volatile File vWalletFile;
|
||||
protected volatile File vTokenWalletFile;
|
||||
private final String walletFilePrefix;
|
||||
private final String tokenWalletFilePrefix;
|
||||
private volatile Wallet vWallet;
|
||||
private volatile Wallet vTokenWallet;
|
||||
private volatile File vWalletFile;
|
||||
private volatile File vTokenWalletFile;
|
||||
@Nullable
|
||||
protected DeterministicSeed restoreWalletFromSeed;
|
||||
private DeterministicSeed btcSeed;
|
||||
@Nullable
|
||||
protected DeterministicSeed restoreTokenWalletFromSeed;
|
||||
private DeterministicSeed squSeed;
|
||||
|
||||
protected final NetworkParameters params;
|
||||
protected volatile BlockChain vChain;
|
||||
protected volatile BlockStore vStore;
|
||||
protected volatile PeerGroup vPeerGroup;
|
||||
protected final File directory;
|
||||
protected boolean useAutoSave = true;
|
||||
protected PeerAddress[] peerAddresses;
|
||||
protected PeerEventListener downloadListener;
|
||||
protected boolean autoStop = true;
|
||||
protected InputStream checkpoints;
|
||||
protected boolean blockingStartup = true;
|
||||
protected boolean useTor = false; // Perhaps in future we can change this to true.
|
||||
protected String userAgent, version;
|
||||
protected WalletProtobufSerializer.WalletFactory walletFactory;
|
||||
final NetworkParameters params;
|
||||
private volatile BlockChain vChain;
|
||||
private volatile BlockStore vStore;
|
||||
private volatile PeerGroup vPeerGroup;
|
||||
private final File directory;
|
||||
private boolean useAutoSave = true;
|
||||
private PeerAddress[] peerAddresses;
|
||||
private PeerEventListener downloadListener;
|
||||
private boolean autoStop = true;
|
||||
private InputStream checkpoints;
|
||||
private boolean blockingStartup = true;
|
||||
private boolean useTor = false; // Perhaps in future we can change this to true.
|
||||
private String userAgent;
|
||||
private String version;
|
||||
private WalletProtobufSerializer.WalletFactory walletFactory;
|
||||
|
||||
@Nullable
|
||||
protected PeerDiscovery discovery;
|
||||
private PeerDiscovery discovery;
|
||||
|
||||
protected volatile Context context;
|
||||
private final Context context;
|
||||
private long bloomFilterTweak = 0;
|
||||
private double bloomFilterFPRate = -1;
|
||||
private int lookaheadSize = -1;
|
||||
|
@ -94,7 +98,7 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
/**
|
||||
* Creates a new WalletAppKitBitSquare, with a newly created {@link Context}. Files will be stored in the given directory.
|
||||
*/
|
||||
public BitSquareWalletAppKit(NetworkParameters params, Socks5Proxy socks5Proxy, File directory, String walletFilePrefix, String tokenWalletFilePrefix) {
|
||||
public WalletConfig(NetworkParameters params, Socks5Proxy socks5Proxy, File directory, String walletFilePrefix, String tokenWalletFilePrefix) {
|
||||
this(new Context(params), directory, walletFilePrefix, tokenWalletFilePrefix);
|
||||
this.socks5Proxy = socks5Proxy;
|
||||
}
|
||||
|
@ -102,21 +106,21 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
/**
|
||||
* Creates a new WalletAppKitBitSquare, with a newly created {@link Context}. Files will be stored in the given directory.
|
||||
*/
|
||||
public BitSquareWalletAppKit(NetworkParameters params, File directory, String walletFilePrefix, String tokenWalletFilePrefix) {
|
||||
private WalletConfig(NetworkParameters params, File directory, String walletFilePrefix, String tokenWalletFilePrefix) {
|
||||
this(new Context(params), directory, walletFilePrefix, tokenWalletFilePrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new WalletAppKitBitSquare, with the given {@link Context}. Files will be stored in the given directory.
|
||||
*/
|
||||
public BitSquareWalletAppKit(Context context, File directory, String walletFilePrefix, String tokenWalletFilePrefix) {
|
||||
private WalletConfig(Context context, File directory, String walletFilePrefix, String tokenWalletFilePrefix) {
|
||||
this.context = context;
|
||||
this.params = checkNotNull(context.getParams());
|
||||
this.directory = checkNotNull(directory);
|
||||
this.walletFilePrefix = checkNotNull(walletFilePrefix);
|
||||
this.tokenWalletFilePrefix = tokenWalletFilePrefix;
|
||||
if (!Utils.isAndroidRuntime()) {
|
||||
InputStream stream = BitSquareWalletAppKit.class.getResourceAsStream("/" + params.getId() + ".checkpoints");
|
||||
InputStream stream = WalletConfig.class.getResourceAsStream("/" + params.getId() + ".checkpoints");
|
||||
if (stream != null)
|
||||
setCheckpoints(stream);
|
||||
}
|
||||
|
@ -126,7 +130,7 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
return socks5Proxy;
|
||||
}
|
||||
|
||||
protected PeerGroup createPeerGroup() throws TimeoutException {
|
||||
private PeerGroup createPeerGroup() throws TimeoutException {
|
||||
// no proxy case.
|
||||
if (socks5Proxy == null) {
|
||||
if (useTor) {
|
||||
|
@ -157,7 +161,7 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
/**
|
||||
* Will only connect to the given addresses. Cannot be called after startup.
|
||||
*/
|
||||
public BitSquareWalletAppKit setPeerNodes(PeerAddress... addresses) {
|
||||
public WalletConfig setPeerNodes(PeerAddress... addresses) {
|
||||
checkState(state() == State.NEW, "Cannot call after startup");
|
||||
this.peerAddresses = addresses;
|
||||
return this;
|
||||
|
@ -166,7 +170,7 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
/**
|
||||
* Will only connect to localhost. Cannot be called after startup.
|
||||
*/
|
||||
public BitSquareWalletAppKit connectToLocalHost() {
|
||||
public WalletConfig connectToLocalHost() {
|
||||
try {
|
||||
final InetAddress localHost = InetAddress.getLocalHost();
|
||||
return setPeerNodes(new PeerAddress(localHost, params.getPort()));
|
||||
|
@ -179,7 +183,7 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
/**
|
||||
* If true, the wallet will save itself to disk automatically whenever it changes.
|
||||
*/
|
||||
public BitSquareWalletAppKit setAutoSave(boolean value) {
|
||||
public WalletConfig setAutoSave(boolean value) {
|
||||
checkState(state() == State.NEW, "Cannot call after startup");
|
||||
useAutoSave = value;
|
||||
return this;
|
||||
|
@ -190,7 +194,7 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
* {@link org.bitcoinj.core.DownloadProgressTracker} is a good choice. This has no effect unless setBlockingStartup(false) has been called
|
||||
* too, due to some missing implementation code.
|
||||
*/
|
||||
public BitSquareWalletAppKit setDownloadListener(PeerEventListener listener) {
|
||||
public WalletConfig setDownloadListener(PeerEventListener listener) {
|
||||
this.downloadListener = listener;
|
||||
return this;
|
||||
}
|
||||
|
@ -198,7 +202,7 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
/**
|
||||
* If true, will register a shutdown hook to stop the library. Defaults to true.
|
||||
*/
|
||||
public BitSquareWalletAppKit setAutoStop(boolean autoStop) {
|
||||
public WalletConfig setAutoStop(boolean autoStop) {
|
||||
this.autoStop = autoStop;
|
||||
return this;
|
||||
}
|
||||
|
@ -207,7 +211,7 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
* If set, the file is expected to contain a checkpoints file calculated with BuildCheckpoints. It makes initial
|
||||
* block sync faster for new users - please refer to the documentation on the bitcoinj website for further details.
|
||||
*/
|
||||
public BitSquareWalletAppKit setCheckpoints(InputStream checkpoints) {
|
||||
public WalletConfig setCheckpoints(InputStream checkpoints) {
|
||||
if (this.checkpoints != null)
|
||||
Utils.closeUnchecked(this.checkpoints);
|
||||
this.checkpoints = checkNotNull(checkpoints);
|
||||
|
@ -216,11 +220,11 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
|
||||
/**
|
||||
* If true (the default) then the startup of this service won't be considered complete until the network has been
|
||||
* brought up, peer connections established and the block chain synchronised. Therefore {@link #startAndWait()} can
|
||||
* brought up, peer connections established and the block chain synchronised. Therefore startAndWait() can
|
||||
* potentially take a very long time. If false, then startup is considered complete once the network activity
|
||||
* begins and peer connections/block chain sync will continue in the background.
|
||||
*/
|
||||
public BitSquareWalletAppKit setBlockingStartup(boolean blockingStartup) {
|
||||
public WalletConfig setBlockingStartup(boolean blockingStartup) {
|
||||
this.blockingStartup = blockingStartup;
|
||||
return this;
|
||||
}
|
||||
|
@ -231,7 +235,7 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
* @param userAgent A short string that should be the name of your app, e.g. "My Wallet"
|
||||
* @param version A short string that contains the version number, e.g. "1.0-BETA"
|
||||
*/
|
||||
public BitSquareWalletAppKit setUserAgent(String userAgent, String version) {
|
||||
public WalletConfig setUserAgent(String userAgent, String version) {
|
||||
this.userAgent = checkNotNull(userAgent);
|
||||
this.version = checkNotNull(version);
|
||||
return this;
|
||||
|
@ -241,7 +245,7 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
* If called, then an embedded Tor client library will be used to connect to the P2P network. The user does not need
|
||||
* any additional software for this: it's all pure Java. As of April 2014 <b>this mode is experimental</b>.
|
||||
*/
|
||||
public BitSquareWalletAppKit useTor() {
|
||||
public WalletConfig useTor() {
|
||||
this.useTor = true;
|
||||
return this;
|
||||
}
|
||||
|
@ -254,35 +258,35 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
* up the new kit. The next time your app starts it should work as normal (that is, don't keep calling this each
|
||||
* time).
|
||||
*/
|
||||
public BitSquareWalletAppKit restoreWalletFromSeed(DeterministicSeed seed) {
|
||||
this.restoreWalletFromSeed = seed;
|
||||
public WalletConfig restoreWalletFromSeed(DeterministicSeed seed) {
|
||||
this.btcSeed = seed;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BitSquareWalletAppKit restoreTokenWalletFromSeed(DeterministicSeed seed) {
|
||||
this.restoreTokenWalletFromSeed = seed;
|
||||
public WalletConfig restoreSquWalletFromSeed(DeterministicSeed seed) {
|
||||
this.squSeed = seed;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the peer discovery class to use. If none is provided then DNS is used, which is a reasonable default.
|
||||
*/
|
||||
public BitSquareWalletAppKit setDiscovery(@Nullable PeerDiscovery discovery) {
|
||||
public WalletConfig setDiscovery(@Nullable PeerDiscovery discovery) {
|
||||
this.discovery = discovery;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BitSquareWalletAppKit setBloomFilterFalsePositiveRate(double bloomFilterFPRate) {
|
||||
public WalletConfig setBloomFilterFalsePositiveRate(double bloomFilterFPRate) {
|
||||
this.bloomFilterFPRate = bloomFilterFPRate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BitSquareWalletAppKit setBloomFilterTweak(long bloomFilterTweak) {
|
||||
public WalletConfig setBloomFilterTweak(long bloomFilterTweak) {
|
||||
this.bloomFilterTweak = bloomFilterTweak;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BitSquareWalletAppKit setLookaheadSize(int lookaheadSize) {
|
||||
public WalletConfig setLookaheadSize(int lookaheadSize) {
|
||||
this.lookaheadSize = lookaheadSize;
|
||||
return this;
|
||||
}
|
||||
|
@ -293,14 +297,14 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
* <p>When this is called, chain(), store(), and peerGroup() will return the created objects, however they are not
|
||||
* initialized/started.</p>
|
||||
*/
|
||||
protected List<WalletExtension> provideWalletExtensions() throws Exception {
|
||||
private List<WalletExtension> provideWalletExtensions() {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this to use a {@link BlockStore} that isn't the default of {@link SPVBlockStore}.
|
||||
*/
|
||||
protected BlockStore provideBlockStore(File file) throws BlockStoreException {
|
||||
private BlockStore provideBlockStore(File file) throws BlockStoreException {
|
||||
return new SPVBlockStore(params, file);
|
||||
}
|
||||
|
||||
|
@ -308,7 +312,7 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
* This method is invoked on a background thread after all objects are initialised, but before the peer group
|
||||
* or block chain download is started. You can tweak the objects configuration here.
|
||||
*/
|
||||
protected void onSetupCompleted() {
|
||||
void onSetupCompleted() {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -349,35 +353,34 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
try {
|
||||
File chainFile = new File(directory, walletFilePrefix + ".spvchain");
|
||||
boolean chainFileExists = chainFile.exists();
|
||||
vWalletFile = new File(directory, walletFilePrefix + ".wallet");
|
||||
boolean shouldReplayWallet = (vWalletFile.exists() && !chainFileExists) || restoreWalletFromSeed != null;
|
||||
|
||||
vWalletFile = new File(directory, walletFilePrefix + ".wallet");
|
||||
boolean shouldReplayBtcWallet = (vWalletFile.exists() && !chainFileExists) || btcSeed != null;
|
||||
BitsquareKeyChainGroup keyChainGroup;
|
||||
if (restoreWalletFromSeed != null)
|
||||
keyChainGroup = new BitsquareKeyChainGroup(params, restoreWalletFromSeed, true);
|
||||
if (btcSeed != null)
|
||||
keyChainGroup = new BitsquareKeyChainGroup(params, btcSeed, true);
|
||||
else
|
||||
keyChainGroup = new BitsquareKeyChainGroup(params, true);
|
||||
vWallet = createOrLoadWallet(vWalletFile, shouldReplayWallet, restoreWalletFromSeed, keyChainGroup);
|
||||
vWallet = createOrLoadWallet(vWalletFile, shouldReplayBtcWallet, btcSeed, squSeed, keyChainGroup);
|
||||
|
||||
vTokenWalletFile = new File(directory, tokenWalletFilePrefix + ".wallet");
|
||||
boolean shouldReplayTokenWallet = (vTokenWalletFile.exists() && !chainFileExists) || restoreTokenWalletFromSeed != null;
|
||||
|
||||
if (restoreWalletFromSeed != null)
|
||||
keyChainGroup = new BitsquareKeyChainGroup(params, restoreWalletFromSeed, false);
|
||||
boolean shouldReplaySquWallet = (vTokenWalletFile.exists() && !chainFileExists) || squSeed != null;
|
||||
if (squSeed != null)
|
||||
keyChainGroup = new BitsquareKeyChainGroup(params, squSeed, false);
|
||||
else
|
||||
keyChainGroup = new BitsquareKeyChainGroup(params, false);
|
||||
vTokenWallet = createOrLoadWallet(vTokenWalletFile, shouldReplayTokenWallet, restoreTokenWalletFromSeed, keyChainGroup);
|
||||
vTokenWallet = createOrLoadWallet(vTokenWalletFile, shouldReplaySquWallet, btcSeed, squSeed, keyChainGroup);
|
||||
|
||||
// Initiate Bitcoin network objects (block store, blockchain and peer group)
|
||||
vStore = provideBlockStore(chainFile);
|
||||
if (!chainFileExists || restoreWalletFromSeed != null || restoreTokenWalletFromSeed != null) {
|
||||
if (!chainFileExists || btcSeed != null || squSeed != null) {
|
||||
if (checkpoints != null) {
|
||||
// Initialize the chain file with a checkpoint to speed up first-run sync.
|
||||
long time;
|
||||
|
||||
if (restoreWalletFromSeed != null || restoreTokenWalletFromSeed != null) {
|
||||
if (btcSeed != null || squSeed != null) {
|
||||
// we created both wallets at the same time
|
||||
time = restoreWalletFromSeed.getCreationTimeSeconds();
|
||||
time = btcSeed.getCreationTimeSeconds();
|
||||
if (chainFileExists) {
|
||||
log.info("Deleting the chain file in preparation from restore.");
|
||||
vStore.close();
|
||||
|
@ -447,7 +450,7 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
public void onFailure(@NotNull Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
|
||||
}
|
||||
|
@ -458,10 +461,13 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
}
|
||||
}
|
||||
|
||||
private Wallet createOrLoadWallet(File walletFile, boolean shouldReplayWallet, DeterministicSeed restoreFromSeed, BitsquareKeyChainGroup keyChainGroup) throws Exception {
|
||||
private Wallet createOrLoadWallet(File walletFile, boolean shouldReplayWallet, @Nullable DeterministicSeed restoreFromBtcSeed, @Nullable DeterministicSeed restoreFromSquSeed, BitsquareKeyChainGroup keyChainGroup) throws Exception {
|
||||
Wallet wallet;
|
||||
|
||||
maybeMoveOldWalletOutOfTheWay(walletFile, restoreFromSeed);
|
||||
if (restoreFromBtcSeed != null)
|
||||
maybeMoveOldWalletOutOfTheWay(walletFile, restoreFromBtcSeed);
|
||||
if (restoreFromSquSeed != null)
|
||||
maybeMoveOldWalletOutOfTheWay(walletFile, restoreFromSquSeed);
|
||||
|
||||
if (walletFile.exists()) {
|
||||
wallet = loadWallet(walletFile, shouldReplayWallet, keyChainGroup.isUseBitcoinDeterministicKeyChain());
|
||||
|
@ -507,7 +513,7 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
return wallet;
|
||||
}
|
||||
|
||||
protected Wallet createWallet(KeyChainGroup keyChainGroup) {
|
||||
private Wallet createWallet(KeyChainGroup keyChainGroup) {
|
||||
if (lookaheadSize != -1)
|
||||
keyChainGroup.setLookaheadSize(lookaheadSize);
|
||||
|
||||
|
@ -540,8 +546,8 @@ public class BitSquareWalletAppKit extends AbstractIdleService {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
BitSquareWalletAppKit.this.stopAsync();
|
||||
BitSquareWalletAppKit.this.awaitTerminated();
|
||||
WalletConfig.this.stopAsync();
|
||||
WalletConfig.this.awaitTerminated();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
|
@ -30,6 +30,7 @@ import io.bitsquare.common.handlers.ResultHandler;
|
|||
import io.bitsquare.user.Preferences;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.crypto.DeterministicKey;
|
||||
import org.bitcoinj.crypto.KeyCrypterScrypt;
|
||||
import org.bitcoinj.crypto.TransactionSignature;
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.bitcoinj.signers.TransactionSigner;
|
||||
|
@ -56,49 +57,74 @@ import static com.google.common.base.Preconditions.checkState;
|
|||
* It startup the wallet app kit and initialized the wallet.
|
||||
*/
|
||||
public abstract class WalletService {
|
||||
protected static final Logger log = LoggerFactory.getLogger(WalletService.class);
|
||||
private static final Logger log = LoggerFactory.getLogger(WalletService.class);
|
||||
|
||||
protected final CopyOnWriteArraySet<AddressConfidenceListener> addressConfidenceListeners = new CopyOnWriteArraySet<>();
|
||||
protected final CopyOnWriteArraySet<TxConfidenceListener> txConfidenceListeners = new CopyOnWriteArraySet<>();
|
||||
protected final CopyOnWriteArraySet<BalanceListener> balanceListeners = new CopyOnWriteArraySet<>();
|
||||
private final CopyOnWriteArraySet<AddressConfidenceListener> addressConfidenceListeners = new CopyOnWriteArraySet<>();
|
||||
private final CopyOnWriteArraySet<TxConfidenceListener> txConfidenceListeners = new CopyOnWriteArraySet<>();
|
||||
private final CopyOnWriteArraySet<BalanceListener> balanceListeners = new CopyOnWriteArraySet<>();
|
||||
|
||||
protected final WalletEventListener walletEventListener = new BitsquareWalletEventListener();
|
||||
protected final NetworkParameters params;
|
||||
final WalletEventListener walletEventListener = new BitsquareWalletEventListener();
|
||||
final NetworkParameters params;
|
||||
|
||||
protected WalletSetup walletSetup;
|
||||
protected final Preferences preferences;
|
||||
protected final FeeService feeService;
|
||||
|
||||
protected Wallet wallet;
|
||||
final WalletsSetup walletsSetup;
|
||||
private final Preferences preferences;
|
||||
private final FeeService feeService;
|
||||
|
||||
Wallet wallet;
|
||||
KeyParameter aesKey;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public WalletService(WalletSetup walletSetup,
|
||||
Preferences preferences,
|
||||
FeeService feeService) {
|
||||
this.walletSetup = walletSetup;
|
||||
WalletService(WalletsSetup walletsSetup,
|
||||
Preferences preferences,
|
||||
FeeService feeService) {
|
||||
this.walletsSetup = walletsSetup;
|
||||
this.preferences = preferences;
|
||||
this.feeService = feeService;
|
||||
|
||||
params = walletSetup.getParams();
|
||||
params = walletsSetup.getParams();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Protected Methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void decryptWallet(@NotNull KeyParameter key) {
|
||||
wallet.decrypt(key);
|
||||
aesKey = null;
|
||||
}
|
||||
|
||||
void encryptWallet(KeyCrypterScrypt keyCrypterScrypt, KeyParameter key) {
|
||||
if (this.aesKey != null) {
|
||||
log.warn("encryptWallet called but we have a aesKey already set. " +
|
||||
"We decryptWallet with the old key before we apply the new key.");
|
||||
decryptWallet(this.aesKey);
|
||||
}
|
||||
|
||||
wallet.encrypt(keyCrypterScrypt, key);
|
||||
aesKey = key;
|
||||
}
|
||||
|
||||
void setAesKey(KeyParameter aesKey) {
|
||||
this.aesKey = aesKey;
|
||||
}
|
||||
|
||||
abstract String getWalletAsString(boolean includePrivKeys);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public Methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
public void shutDown() {
|
||||
if (wallet != null)
|
||||
wallet.removeEventListener(walletEventListener);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Listener
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -132,7 +158,7 @@ public abstract class WalletService {
|
|||
// Checks
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
protected void checkWalletConsistency() throws WalletException {
|
||||
void checkWalletConsistency() throws WalletException {
|
||||
try {
|
||||
log.trace("Check if wallet is consistent before commit.");
|
||||
checkNotNull(wallet);
|
||||
|
@ -144,7 +170,7 @@ public abstract class WalletService {
|
|||
}
|
||||
}
|
||||
|
||||
protected void verifyTransaction(Transaction transaction) throws TransactionVerificationException {
|
||||
void verifyTransaction(Transaction transaction) throws TransactionVerificationException {
|
||||
try {
|
||||
log.trace("Verify transaction " + transaction);
|
||||
transaction.verify();
|
||||
|
@ -155,13 +181,13 @@ public abstract class WalletService {
|
|||
}
|
||||
}
|
||||
|
||||
protected void checkScriptSigs(Transaction transaction) throws TransactionVerificationException {
|
||||
void checkScriptSigs(Transaction transaction) throws TransactionVerificationException {
|
||||
for (int i = 0; i < transaction.getInputs().size(); i++) {
|
||||
checkScriptSig(transaction, transaction.getInputs().get(i), i);
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkScriptSig(Transaction transaction, TransactionInput input, int inputIndex) throws TransactionVerificationException {
|
||||
void checkScriptSig(Transaction transaction, TransactionInput input, int inputIndex) throws TransactionVerificationException {
|
||||
try {
|
||||
log.trace("Verifies that this script (interpreted as a scriptSig) correctly spends the given scriptPubKey. Check input at index: " + inputIndex);
|
||||
checkNotNull(input.getConnectedOutput(), "input.getConnectedOutput() must not be null");
|
||||
|
@ -177,6 +203,7 @@ public abstract class WalletService {
|
|||
// Sign tx
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//TODOcheck with signTransactionInput
|
||||
/* protected void signInput(Transaction transaction) throws SigningException {
|
||||
List<TransactionInput> inputs = transaction.getInputs();
|
||||
|
||||
|
@ -189,9 +216,9 @@ public abstract class WalletService {
|
|||
ECKey sigKey = input.getOutpoint().getConnectedKey(wallet);
|
||||
checkNotNull(sigKey, "signInput: sigKey must not be null. input.getOutpoint()=" + input.getOutpoint().toString());
|
||||
if (sigKey.isEncrypted())
|
||||
checkNotNull(walletSetup.getAesKey());
|
||||
checkNotNull(aesKey);
|
||||
Sha256Hash hash = transaction.hashForSignature(inputIndex, scriptPubKey, Transaction.SigHash.ALL, false);
|
||||
ECKey.ECDSASignature signature = sigKey.sign(hash, walletSetup.getAesKey());
|
||||
ECKey.ECDSASignature signature = sigKey.sign(hash, aesKey);
|
||||
TransactionSignature txSig = new TransactionSignature(signature, Transaction.SigHash.ALL, false);
|
||||
if (scriptPubKey.isSentToRawPubKey()) {
|
||||
input.setScriptSig(ScriptBuilder.createInputScript(txSig));
|
||||
|
@ -202,8 +229,8 @@ public abstract class WalletService {
|
|||
}
|
||||
}*/
|
||||
|
||||
public void signTransactionInput(Transaction tx, TransactionInput txIn, int index) {
|
||||
KeyBag maybeDecryptingKeyBag = new DecryptingKeyBag(wallet, walletSetup.getAesKey());
|
||||
void signTransactionInput(Transaction tx, TransactionInput txIn, int index) {
|
||||
KeyBag maybeDecryptingKeyBag = new DecryptingKeyBag(wallet, aesKey);
|
||||
if (txIn.getConnectedOutput() != null) {
|
||||
try {
|
||||
// We assume if its already signed, its hopefully got a SIGHASH type that will not invalidate when
|
||||
|
@ -297,7 +324,7 @@ public abstract class WalletService {
|
|||
return null;
|
||||
}
|
||||
|
||||
protected TransactionConfidence getTransactionConfidence(Transaction tx, Address address) {
|
||||
private TransactionConfidence getTransactionConfidence(Transaction tx, Address address) {
|
||||
List<TransactionOutput> mergedOutputs = getOutputsWithConnectedOutputs(tx);
|
||||
List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
|
||||
|
||||
|
@ -312,7 +339,7 @@ public abstract class WalletService {
|
|||
}
|
||||
|
||||
|
||||
protected List<TransactionOutput> getOutputsWithConnectedOutputs(Transaction tx) {
|
||||
private List<TransactionOutput> getOutputsWithConnectedOutputs(Transaction tx) {
|
||||
List<TransactionOutput> transactionOutputs = tx.getOutputs();
|
||||
List<TransactionOutput> connectedOutputs = new ArrayList<>();
|
||||
|
||||
|
@ -332,7 +359,7 @@ public abstract class WalletService {
|
|||
}
|
||||
|
||||
|
||||
protected TransactionConfidence getMostRecentConfidence(List<TransactionConfidence> transactionConfidenceList) {
|
||||
private TransactionConfidence getMostRecentConfidence(List<TransactionConfidence> transactionConfidenceList) {
|
||||
TransactionConfidence transactionConfidence = null;
|
||||
for (TransactionConfidence confidence : transactionConfidenceList) {
|
||||
if (confidence != null) {
|
||||
|
@ -363,7 +390,7 @@ public abstract class WalletService {
|
|||
return wallet != null ? getBalance(wallet.calculateAllSpendCandidates(), address) : Coin.ZERO;
|
||||
}
|
||||
|
||||
protected Coin getBalance(List<TransactionOutput> transactionOutputs, Address address) {
|
||||
private Coin getBalance(List<TransactionOutput> transactionOutputs, Address address) {
|
||||
Coin balance = Coin.ZERO;
|
||||
for (TransactionOutput transactionOutput : transactionOutputs) {
|
||||
if (transactionOutput.getScriptPubKey().isSentToAddress() || transactionOutput.getScriptPubKey().isPayToScriptHash()) {
|
||||
|
@ -389,7 +416,7 @@ public abstract class WalletService {
|
|||
return outputs;
|
||||
}
|
||||
|
||||
protected Coin getTxFeeForWithdrawalPerByte() {
|
||||
Coin getTxFeeForWithdrawalPerByte() {
|
||||
Coin fee = (preferences.getUseCustomWithdrawalTxFee()) ?
|
||||
Coin.valueOf(preferences.getWithdrawalTxFeeInBytes()) :
|
||||
feeService.getTxFeePerByte();
|
||||
|
@ -460,7 +487,7 @@ public abstract class WalletService {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
protected class BitsquareWalletEventListener extends AbstractWalletEventListener {
|
||||
class BitsquareWalletEventListener extends AbstractWalletEventListener {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
notifyBalanceListeners(tx);
|
||||
|
@ -490,7 +517,7 @@ public abstract class WalletService {
|
|||
txConfidenceListener.onTransactionConfidenceChanged(tx.getConfidence()));
|
||||
}
|
||||
|
||||
protected void notifyBalanceListeners(Transaction tx) {
|
||||
void notifyBalanceListeners(Transaction tx) {
|
||||
for (BalanceListener balanceListener : balanceListeners) {
|
||||
Coin balance;
|
||||
if (balanceListener.getAddress() != null)
|
135
core/src/main/java/io/bitsquare/btc/wallet/WalletsManager.java
Normal file
135
core/src/main/java/io/bitsquare/btc/wallet/WalletsManager.java
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* This file is part of Bitsquare.
|
||||
*
|
||||
* Bitsquare is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.bitsquare.common.handlers.ExceptionHandler;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
import io.bitsquare.crypto.ScryptUtil;
|
||||
import org.bitcoinj.core.Wallet;
|
||||
import org.bitcoinj.crypto.KeyCrypter;
|
||||
import org.bitcoinj.crypto.KeyCrypterScrypt;
|
||||
import org.bitcoinj.wallet.DeterministicSeed;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongycastle.crypto.params.KeyParameter;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class WalletsManager {
|
||||
private static final Logger log = LoggerFactory.getLogger(WalletsManager.class);
|
||||
private final BtcWalletService btcWalletService;
|
||||
private final TradeWalletService tradeWalletService;
|
||||
private final SquWalletService squWalletService;
|
||||
private final WalletsSetup walletsSetup;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public WalletsManager(BtcWalletService btcWalletService, TradeWalletService tradeWalletService, SquWalletService squWalletService, WalletsSetup walletsSetup) {
|
||||
this.btcWalletService = btcWalletService;
|
||||
this.tradeWalletService = tradeWalletService;
|
||||
this.squWalletService = squWalletService;
|
||||
this.walletsSetup = walletsSetup;
|
||||
}
|
||||
|
||||
public void decryptWallets(KeyParameter aesKey) {
|
||||
btcWalletService.decryptWallet(aesKey);
|
||||
squWalletService.decryptWallet(aesKey);
|
||||
tradeWalletService.setAesKey(null);
|
||||
}
|
||||
|
||||
public void encryptWallets(KeyCrypterScrypt keyCrypterScrypt, KeyParameter aesKey) {
|
||||
squWalletService.encryptWallet(keyCrypterScrypt, aesKey);
|
||||
btcWalletService.encryptWallet(keyCrypterScrypt, aesKey);
|
||||
|
||||
// we save the key for the trade wallet as we don't require passwords here
|
||||
tradeWalletService.setAesKey(aesKey);
|
||||
}
|
||||
|
||||
public String getWalletsAsString(boolean includePrivKeys) {
|
||||
return "BTC Wallet:\n" +
|
||||
btcWalletService.getWalletAsString(includePrivKeys) +
|
||||
"\n\nSQU Wallet:\n" +
|
||||
squWalletService.getWalletAsString(includePrivKeys);
|
||||
}
|
||||
|
||||
public void restoreSeedWords(@Nullable DeterministicSeed btcSeed, @Nullable DeterministicSeed squSeed, ResultHandler resultHandler, ExceptionHandler exceptionHandler) {
|
||||
walletsSetup.restoreSeedWords(btcSeed, squSeed, resultHandler, exceptionHandler);
|
||||
}
|
||||
|
||||
public void backupWallets() {
|
||||
walletsSetup.backupWallets();
|
||||
}
|
||||
|
||||
public void clearBackup() {
|
||||
walletsSetup.clearBackups();
|
||||
}
|
||||
|
||||
public boolean areWalletsEncrypted() {
|
||||
return getBtcWallet() != null && getBtcWallet().isEncrypted();
|
||||
}
|
||||
|
||||
public boolean areWalletsAvailable() {
|
||||
return getBtcWallet() != null;
|
||||
}
|
||||
|
||||
private Wallet getBtcWallet() {
|
||||
return btcWalletService.getWallet();
|
||||
}
|
||||
|
||||
public KeyCrypterScrypt getKeyCrypterScrypt() {
|
||||
if (areWalletsEncrypted())
|
||||
return (KeyCrypterScrypt) getBtcWallet().getKeyCrypter();
|
||||
else
|
||||
return ScryptUtil.getKeyCrypterScrypt();
|
||||
}
|
||||
|
||||
public boolean checkAESKey(KeyParameter aesKey) {
|
||||
return getBtcWallet() != null && getBtcWallet().checkAESKey(aesKey);
|
||||
}
|
||||
|
||||
public long getChainSeedCreationTimeSeconds() {
|
||||
return getBtcWallet() != null ? getBtcWallet().getKeyChainSeed().getCreationTimeSeconds() : 0;
|
||||
}
|
||||
|
||||
public boolean hasPositiveBalance() {
|
||||
return getBtcWallet() != null &&
|
||||
(getBtcWallet().getBalance(Wallet.BalanceType.AVAILABLE).value > 0 ||
|
||||
squWalletService.getWallet().getBalance(Wallet.BalanceType.AVAILABLE).value > 0);
|
||||
}
|
||||
|
||||
public void setAesKey(KeyParameter aesKey) {
|
||||
btcWalletService.setAesKey(aesKey);
|
||||
squWalletService.setAesKey(aesKey);
|
||||
tradeWalletService.setAesKey(aesKey);
|
||||
}
|
||||
|
||||
public DeterministicSeed getDecryptedSeed(KeyParameter aesKey, Wallet wallet) {
|
||||
KeyCrypter btcKeyCrypter = wallet.getKeyCrypter();
|
||||
if (btcKeyCrypter != null) {
|
||||
DeterministicSeed btcKeyChainSeed = wallet.getKeyChainSeed();
|
||||
return btcKeyChainSeed.decrypt(btcKeyCrypter, "", aesKey);
|
||||
} else {
|
||||
log.warn("keyCrypter is null");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,13 +15,13 @@
|
|||
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.bitsquare.btc;
|
||||
package io.bitsquare.btc.wallet;
|
||||
|
||||
import com.google.common.util.concurrent.Service;
|
||||
import com.google.inject.Inject;
|
||||
import com.runjva.sourceforge.jsocks.protocol.Socks5Proxy;
|
||||
import io.bitsquare.app.Log;
|
||||
import io.bitsquare.btc.provider.fee.FeeService;
|
||||
import io.bitsquare.btc.*;
|
||||
import io.bitsquare.common.Timer;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.ExceptionHandler;
|
||||
|
@ -32,8 +32,6 @@ import io.bitsquare.storage.Storage;
|
|||
import io.bitsquare.user.Preferences;
|
||||
import javafx.beans.property.*;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.crypto.DeterministicKey;
|
||||
import org.bitcoinj.crypto.KeyCrypterScrypt;
|
||||
import org.bitcoinj.net.discovery.SeedPeers;
|
||||
import org.bitcoinj.params.MainNetParams;
|
||||
import org.bitcoinj.params.RegTestParams;
|
||||
|
@ -57,8 +55,10 @@ import java.util.*;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
public class WalletSetup {
|
||||
private static final Logger log = LoggerFactory.getLogger(WalletSetup.class);
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
public class WalletsSetup {
|
||||
private static final Logger log = LoggerFactory.getLogger(WalletsSetup.class);
|
||||
|
||||
private static final long STARTUP_TIMEOUT_SEC = 60;
|
||||
|
||||
|
@ -67,15 +67,14 @@ public class WalletSetup {
|
|||
private final AddressEntryList addressEntryList;
|
||||
private final UserAgent userAgent;
|
||||
private final Preferences preferences;
|
||||
private final FeeService feeService;
|
||||
private final Socks5ProxyProvider socks5ProxyProvider;
|
||||
private final NetworkParameters params;
|
||||
private final File walletDir;
|
||||
private BitSquareWalletAppKit walletAppKit;
|
||||
private Wallet wallet;
|
||||
private Wallet tokenWallet;
|
||||
private String walletFileName = "Bitsquare";
|
||||
private String tokenWalletFileName = "SQU";
|
||||
private WalletConfig walletConfig;
|
||||
private Wallet btcWallet;
|
||||
private Wallet squWallet;
|
||||
private final String walletFileName = "Bitsquare";
|
||||
private final String tokenWalletFileName = "SQU";
|
||||
private final Long bloomFilterTweak;
|
||||
private KeyParameter aesKey;
|
||||
private final Storage<Long> storage;
|
||||
|
@ -84,25 +83,23 @@ public class WalletSetup {
|
|||
private final ObjectProperty<List<Peer>> connectedPeers = new SimpleObjectProperty<>();
|
||||
private final DownloadListener downloadListener = new DownloadListener();
|
||||
// private final WalletEventListener walletEventListener = new BitsquareWalletEventListener();
|
||||
private List<Runnable> setupCompletedHandlers = new ArrayList<>();
|
||||
private final List<Runnable> setupCompletedHandlers = new ArrayList<>();
|
||||
|
||||
|
||||
@Inject
|
||||
public WalletSetup(RegTestHost regTestHost,
|
||||
TradeWalletService tradeWalletService,
|
||||
AddressEntryList addressEntryList,
|
||||
UserAgent userAgent,
|
||||
Preferences preferences,
|
||||
FeeService feeService,
|
||||
Socks5ProxyProvider socks5ProxyProvider,
|
||||
@Named(BtcOptionKeys.WALLET_DIR) File appDir) {
|
||||
public WalletsSetup(RegTestHost regTestHost,
|
||||
TradeWalletService tradeWalletService,
|
||||
AddressEntryList addressEntryList,
|
||||
UserAgent userAgent,
|
||||
Preferences preferences,
|
||||
Socks5ProxyProvider socks5ProxyProvider,
|
||||
@Named(BtcOptionKeys.WALLET_DIR) File appDir) {
|
||||
|
||||
this.regTestHost = regTestHost;
|
||||
this.tradeWalletService = tradeWalletService;
|
||||
this.addressEntryList = addressEntryList;
|
||||
this.userAgent = userAgent;
|
||||
this.preferences = preferences;
|
||||
this.feeService = feeService;
|
||||
this.socks5ProxyProvider = socks5ProxyProvider;
|
||||
|
||||
params = preferences.getBitcoinNetwork().getParameters();
|
||||
|
@ -118,7 +115,7 @@ public class WalletSetup {
|
|||
}
|
||||
}
|
||||
|
||||
public void initialize(@Nullable DeterministicSeed seed, ResultHandler resultHandler, ExceptionHandler exceptionHandler) {
|
||||
public void initialize(@Nullable DeterministicSeed btcSeed, @Nullable DeterministicSeed squSeed, ResultHandler resultHandler, ExceptionHandler exceptionHandler) {
|
||||
Log.traceCall();
|
||||
|
||||
// Tell bitcoinj to execute event handlers on the JavaFX UI thread. This keeps things simple and means
|
||||
|
@ -138,26 +135,26 @@ public class WalletSetup {
|
|||
log.debug("Use socks5Proxy for bitcoinj: " + socks5Proxy);
|
||||
|
||||
// If seed is non-null it means we are restoring from backup.
|
||||
walletAppKit = new BitSquareWalletAppKit(params, socks5Proxy, walletDir, walletFileName, tokenWalletFileName) {
|
||||
walletConfig = new WalletConfig(params, socks5Proxy, walletDir, walletFileName, tokenWalletFileName) {
|
||||
@Override
|
||||
protected void onSetupCompleted() {
|
||||
wallet = walletAppKit.wallet();
|
||||
tokenWallet = walletAppKit.tokenWallet();
|
||||
btcWallet = walletConfig.wallet();
|
||||
squWallet = walletConfig.tokenWallet();
|
||||
|
||||
// Don't make the user wait for confirmations for now, as the intention is they're sending it
|
||||
// their own money!
|
||||
wallet.allowSpendingUnconfirmedTransactions();
|
||||
tokenWallet.allowSpendingUnconfirmedTransactions();
|
||||
btcWallet.allowSpendingUnconfirmedTransactions();
|
||||
squWallet.allowSpendingUnconfirmedTransactions();
|
||||
|
||||
if (params != RegTestParams.get())
|
||||
walletAppKit.peerGroup().setMaxConnections(11);
|
||||
walletConfig.peerGroup().setMaxConnections(11);
|
||||
|
||||
// wallet.addEventListener(walletEventListener);
|
||||
|
||||
addressEntryList.onWalletReady(wallet);
|
||||
addressEntryList.onWalletReady(btcWallet);
|
||||
|
||||
|
||||
walletAppKit.peerGroup().addEventListener(new PeerEventListener() {
|
||||
walletConfig.peerGroup().addEventListener(new PeerEventListener() {
|
||||
@Override
|
||||
public void onPeersDiscovered(Set<PeerAddress> peerAddresses) {
|
||||
}
|
||||
|
@ -173,13 +170,13 @@ public class WalletSetup {
|
|||
@Override
|
||||
public void onPeerConnected(Peer peer, int peerCount) {
|
||||
numPeers.set(peerCount);
|
||||
connectedPeers.set(walletAppKit.peerGroup().getConnectedPeers());
|
||||
connectedPeers.set(walletConfig.peerGroup().getConnectedPeers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPeerDisconnected(Peer peer, int peerCount) {
|
||||
numPeers.set(peerCount);
|
||||
connectedPeers.set(walletAppKit.peerGroup().getConnectedPeers());
|
||||
connectedPeers.set(walletConfig.peerGroup().getConnectedPeers());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -199,7 +196,7 @@ public class WalletSetup {
|
|||
});
|
||||
|
||||
// set after wallet is ready
|
||||
tradeWalletService.setWalletAppKit(walletAppKit);
|
||||
tradeWalletService.setWalletConfig(walletConfig);
|
||||
tradeWalletService.setAddressEntryList(addressEntryList);
|
||||
timeoutTimer.stop();
|
||||
|
||||
|
@ -216,7 +213,7 @@ public class WalletSetup {
|
|||
|
||||
// Bitsquare's BitcoinJ fork has added a bloomFilterTweak (nonce) setter to reuse the same seed avoiding the trivial vulnerability
|
||||
// by getting the real pub keys by intersections of several filters sent at each startup.
|
||||
walletAppKit.setBloomFilterTweak(bloomFilterTweak);
|
||||
walletConfig.setBloomFilterTweak(bloomFilterTweak);
|
||||
|
||||
// Avoid the simple attack (see: https://jonasnick.github.io/blog/2015/02/12/privacy-in-bitcoinj/) due to the
|
||||
// default implementation using both pubkey and hash of pubkey. We have set a insertPubKey flag in BasicKeyChain to default false.
|
||||
|
@ -225,7 +222,7 @@ public class WalletSetup {
|
|||
// the threshold. To avoid reaching the threshold we create much more keys which are unlikely to cause update of the
|
||||
// filter for most users. With lookaheadSize of 500 we get 1333 keys which should be enough for most users to
|
||||
// never need to update a bloom filter, which would weaken privacy.
|
||||
walletAppKit.setLookaheadSize(500);
|
||||
walletConfig.setLookaheadSize(500);
|
||||
|
||||
// Calculation is derived from: https://www.reddit.com/r/Bitcoin/comments/2vrx6n/privacy_in_bitcoinj_android_wallet_multibit_hive/coknjuz
|
||||
// No. of false positives (56M keys in the blockchain):
|
||||
|
@ -243,7 +240,7 @@ public class WalletSetup {
|
|||
// For now to reduce risks with high bandwidth consumption we reduce the FP rate by half.
|
||||
// FP rate = 0,00005; No. of false positives: 0,00005 * 56 000 000 = 2800
|
||||
// 1333 / (2800 + 1333) = 0.32 -> 32 % probability that a pub key is in our wallet
|
||||
walletAppKit.setBloomFilterFalsePositiveRate(0.00005);
|
||||
walletConfig.setBloomFilterFalsePositiveRate(0.00005);
|
||||
|
||||
String btcNodes = preferences.getBitcoinNodes();
|
||||
log.debug("btcNodes: " + btcNodes);
|
||||
|
@ -284,7 +281,7 @@ public class WalletSetup {
|
|||
PeerAddress peerAddressListFixed[] = new PeerAddress[peerAddressList.size()];
|
||||
log.debug("btcNodes parsed: " + Arrays.toString(peerAddressListFixed));
|
||||
|
||||
walletAppKit.setPeerNodes(peerAddressList.toArray(peerAddressListFixed));
|
||||
walletConfig.setPeerNodes(peerAddressList.toArray(peerAddressListFixed));
|
||||
usePeerNodes = true;
|
||||
}
|
||||
}
|
||||
|
@ -294,13 +291,13 @@ public class WalletSetup {
|
|||
if (params == RegTestParams.get()) {
|
||||
if (regTestHost == RegTestHost.REG_TEST_SERVER) {
|
||||
try {
|
||||
walletAppKit.setPeerNodes(new PeerAddress(InetAddress.getByName(RegTestHost.SERVER_IP), params.getPort()));
|
||||
walletConfig.setPeerNodes(new PeerAddress(InetAddress.getByName(RegTestHost.SERVER_IP), params.getPort()));
|
||||
usePeerNodes = true;
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else if (regTestHost == RegTestHost.LOCALHOST) {
|
||||
walletAppKit.connectToLocalHost(); // You should run a regtest mode bitcoind locally.}
|
||||
walletConfig.connectToLocalHost(); // You should run a regtest mode bitcoind locally.}
|
||||
}
|
||||
} else if (params == MainNetParams.get()) {
|
||||
// Checkpoints are block headers that ship inside our app: for a new user, we pick the last header
|
||||
|
@ -308,13 +305,13 @@ public class WalletSetup {
|
|||
// Checkpoint files are made using the BuildCheckpoints tool and usually we have to download the
|
||||
// last months worth or more (takes a few seconds).
|
||||
try {
|
||||
walletAppKit.setCheckpoints(getClass().getResourceAsStream("/wallet/checkpoints"));
|
||||
walletConfig.setCheckpoints(getClass().getResourceAsStream("/wallet/checkpoints"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
log.error(e.toString());
|
||||
}
|
||||
} else if (params == TestNet3Params.get()) {
|
||||
walletAppKit.setCheckpoints(getClass().getResourceAsStream("/wallet/checkpoints.testnet"));
|
||||
walletConfig.setCheckpoints(getClass().getResourceAsStream("/wallet/checkpoints.testnet"));
|
||||
}
|
||||
|
||||
// If operating over a proxy and we haven't set any peer nodes, then
|
||||
|
@ -331,31 +328,35 @@ public class WalletSetup {
|
|||
if (socks5Proxy != null && !usePeerNodes) {
|
||||
// SeedPeersSocks5Dns should replace SeedPeers once working reliably.
|
||||
// SeedPeers uses hard coded stable addresses (from MainNetParams). It should be updated from time to time.
|
||||
walletAppKit.setDiscovery(new SeedPeers(params));
|
||||
walletConfig.setDiscovery(new SeedPeers(params));
|
||||
}
|
||||
|
||||
walletAppKit.setDownloadListener(downloadListener)
|
||||
walletConfig.setDownloadListener(downloadListener)
|
||||
.setBlockingStartup(false)
|
||||
.setUserAgent(userAgent.getName(), userAgent.getVersion())
|
||||
.restoreWalletFromSeed(seed);
|
||||
.setUserAgent(userAgent.getName(), userAgent.getVersion());
|
||||
|
||||
walletAppKit.addListener(new Service.Listener() {
|
||||
if (btcSeed != null)
|
||||
walletConfig.restoreWalletFromSeed(btcSeed);
|
||||
if (squSeed != null)
|
||||
walletConfig.restoreSquWalletFromSeed(squSeed);
|
||||
|
||||
walletConfig.addListener(new Service.Listener() {
|
||||
@Override
|
||||
public void failed(@NotNull Service.State from, @NotNull Throwable failure) {
|
||||
walletAppKit = null;
|
||||
walletConfig = null;
|
||||
log.error("walletAppKit failed");
|
||||
timeoutTimer.stop();
|
||||
UserThread.execute(() -> exceptionHandler.handleException(failure));
|
||||
}
|
||||
}, Threading.USER_THREAD);
|
||||
walletAppKit.startAsync();
|
||||
walletConfig.startAsync();
|
||||
}
|
||||
|
||||
public void shutDown() {
|
||||
if (walletAppKit != null) {
|
||||
if (walletConfig != null) {
|
||||
try {
|
||||
walletAppKit.stopAsync();
|
||||
walletAppKit.awaitTerminated(5, TimeUnit.SECONDS);
|
||||
walletConfig.stopAsync();
|
||||
walletConfig.awaitTerminated(5, TimeUnit.SECONDS);
|
||||
} catch (Throwable e) {
|
||||
// ignore
|
||||
}
|
||||
|
@ -363,12 +364,12 @@ public class WalletSetup {
|
|||
}
|
||||
}
|
||||
|
||||
public void backupWallets() {
|
||||
void backupWallets() {
|
||||
FileUtil.rollingBackup(walletDir, walletFileName + ".wallet", 20);
|
||||
FileUtil.rollingBackup(walletDir, tokenWalletFileName + ".wallet", 20);
|
||||
}
|
||||
|
||||
public void clearBackup() {
|
||||
void clearBackups() {
|
||||
try {
|
||||
FileUtil.deleteDirectory(new File(Paths.get(walletDir.getAbsolutePath(), "backup").toString()));
|
||||
} catch (IOException e) {
|
||||
|
@ -381,24 +382,20 @@ public class WalletSetup {
|
|||
setupCompletedHandlers.add(handler);
|
||||
}
|
||||
|
||||
public Wallet getWallet() {
|
||||
return wallet;
|
||||
public Wallet getBtcWallet() {
|
||||
return btcWallet;
|
||||
}
|
||||
|
||||
public Wallet getTokenWallet() {
|
||||
return tokenWallet;
|
||||
public Wallet getSquWallet() {
|
||||
return squWallet;
|
||||
}
|
||||
|
||||
public NetworkParameters getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public KeyParameter getAesKey() {
|
||||
return aesKey;
|
||||
}
|
||||
|
||||
public BlockChain chain() {
|
||||
return walletAppKit.chain();
|
||||
public BlockChain getChain() {
|
||||
return walletConfig.chain();
|
||||
}
|
||||
|
||||
public ReadOnlyIntegerProperty numPeersProperty() {
|
||||
|
@ -413,66 +410,10 @@ public class WalletSetup {
|
|||
return downloadListener.percentageProperty();
|
||||
}
|
||||
|
||||
public void setAesKey(KeyParameter aesKey) {
|
||||
this.aesKey = aesKey;
|
||||
public PeerGroup getPeerGroup() {
|
||||
return walletConfig.peerGroup();
|
||||
}
|
||||
|
||||
public void decryptWallets(@NotNull KeyParameter key) {
|
||||
wallet.decrypt(key);
|
||||
tokenWallet.decrypt(key);
|
||||
|
||||
addressEntryList.stream().forEach(e -> {
|
||||
final DeterministicKey keyPair = e.getKeyPair();
|
||||
if (keyPair != null && keyPair.isEncrypted())
|
||||
e.setDeterministicKey(keyPair.decrypt(key));
|
||||
});
|
||||
|
||||
setAesKey(null);
|
||||
addressEntryList.queueUpForSave();
|
||||
}
|
||||
|
||||
public void encryptWallets(KeyCrypterScrypt keyCrypterScrypt, KeyParameter key) {
|
||||
if (this.aesKey != null) {
|
||||
log.warn("encryptWallet called but we have a aesKey already set. " +
|
||||
"We decryptWallet with the old key before we apply the new key.");
|
||||
decryptWallets(this.aesKey);
|
||||
}
|
||||
|
||||
wallet.encrypt(keyCrypterScrypt, key);
|
||||
tokenWallet.encrypt(keyCrypterScrypt, key);
|
||||
|
||||
addressEntryList.stream().forEach(e -> {
|
||||
final DeterministicKey keyPair = e.getKeyPair();
|
||||
if (keyPair != null && keyPair.isEncrypted())
|
||||
e.setDeterministicKey(keyPair.encrypt(keyCrypterScrypt, key));
|
||||
});
|
||||
setAesKey(key);
|
||||
addressEntryList.queueUpForSave();
|
||||
}
|
||||
|
||||
public PeerGroup peerGroup() {
|
||||
return walletAppKit.peerGroup();
|
||||
}
|
||||
/* public String exportWalletData(boolean includePrivKeys) {
|
||||
StringBuilder addressEntryListData = new StringBuilder();
|
||||
getAddressEntryListAsImmutableList().stream().forEach(e -> addressEntryListData.append(e.toString()).append("\n"));
|
||||
return "BitcoinJ wallet:\n" +
|
||||
wallet.toString(includePrivKeys, true, true, walletAppKit.chain()) + "\n\n" +
|
||||
"Bitsquare address entry list:\n" +
|
||||
addressEntryListData.toString() +
|
||||
"All pubkeys as hex:\n" +
|
||||
wallet.printAllPubKeysAsHex();
|
||||
}
|
||||
|
||||
public String exportTokenWalletData(boolean includePrivKeys) {
|
||||
StringBuilder addressEntryListData = new StringBuilder();
|
||||
return "BitcoinJ SQU wallet:\n" +
|
||||
tokenWallet.toString(includePrivKeys, true, true, walletAppKit.chain()) + "\n\n" +
|
||||
"SQU address entry list:\n" +
|
||||
addressEntryListData.toString() +
|
||||
"All pubkeys as hex:\n" +
|
||||
tokenWallet.printAllPubKeysAsHex();
|
||||
}*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Inner classes
|
||||
|
@ -498,62 +439,19 @@ public class WalletSetup {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*private class BitsquareWalletEventListener extends AbstractWalletEventListener {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
notifyBalanceListeners(tx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
notifyBalanceListeners(tx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) {
|
||||
for (AddressConfidenceListener addressConfidenceListener : addressConfidenceListeners) {
|
||||
List<TransactionConfidence> transactionConfidenceList = new ArrayList<>();
|
||||
transactionConfidenceList.add(getTransactionConfidence(tx, addressConfidenceListener.getAddress()));
|
||||
|
||||
TransactionConfidence transactionConfidence = getMostRecentConfidence(transactionConfidenceList);
|
||||
addressConfidenceListener.onTransactionConfidenceChanged(transactionConfidence);
|
||||
}
|
||||
|
||||
txConfidenceListeners.stream()
|
||||
.filter(txConfidenceListener -> tx != null &&
|
||||
tx.getHashAsString() != null &&
|
||||
txConfidenceListener != null &&
|
||||
tx.getHashAsString().equals(txConfidenceListener.getTxID()))
|
||||
.forEach(txConfidenceListener ->
|
||||
txConfidenceListener.onTransactionConfidenceChanged(tx.getConfidence()));
|
||||
}
|
||||
|
||||
private void notifyBalanceListeners(Transaction tx) {
|
||||
for (BalanceListener balanceListener : balanceListeners) {
|
||||
Coin balance;
|
||||
if (balanceListener.getAddress() != null)
|
||||
balance = getBalanceForAddress(balanceListener.getAddress());
|
||||
else
|
||||
balance = getAvailableBalance();
|
||||
|
||||
balanceListener.onBalanceChanged(balance, tx);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
public void restoreBtcSeedWords(DeterministicSeed seed, ResultHandler resultHandler, ExceptionHandler exceptionHandler) {
|
||||
public void restoreSeedWords(@Nullable DeterministicSeed btcSeed, @Nullable DeterministicSeed squSeed, ResultHandler resultHandler, ExceptionHandler exceptionHandler) {
|
||||
checkArgument(btcSeed != null || squSeed != null, "Either btcSeed or squSeed must be set.");
|
||||
Context ctx = Context.get();
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Context.propagate(ctx);
|
||||
walletAppKit.stopAsync();
|
||||
walletAppKit.awaitTerminated();
|
||||
initialize(seed, resultHandler, exceptionHandler);
|
||||
walletConfig.stopAsync();
|
||||
walletConfig.awaitTerminated();
|
||||
initialize(btcSeed, squSeed, resultHandler, exceptionHandler);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
log.error("Executing task failed. " + t.getMessage());
|
||||
}
|
||||
}, "RestoreWallet-%d").start();
|
||||
}, "RestoreBTCWallet-%d").start();
|
||||
}
|
||||
}
|
|
@ -25,8 +25,8 @@ import io.bitsquare.app.Log;
|
|||
import io.bitsquare.app.Version;
|
||||
import io.bitsquare.arbitration.Arbitrator;
|
||||
import io.bitsquare.arbitration.ArbitratorManager;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.TradeWalletService;
|
||||
import io.bitsquare.common.crypto.KeyRing;
|
||||
import io.bitsquare.common.taskrunner.Model;
|
||||
import io.bitsquare.crypto.DecryptedMsgWithPubKey;
|
||||
|
|
|
@ -22,9 +22,9 @@ import io.bitsquare.app.Log;
|
|||
import io.bitsquare.arbitration.ArbitratorManager;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.AddressEntryException;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.provider.price.PriceFeedService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.TradeWalletService;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.crypto.KeyRing;
|
||||
import io.bitsquare.common.handlers.ErrorMessageHandler;
|
||||
|
@ -436,7 +436,7 @@ public class TradeManager {
|
|||
removeTrade(trade);
|
||||
}
|
||||
|
||||
public void removeTrade(Trade trade) {
|
||||
private void removeTrade(Trade trade) {
|
||||
trades.remove(trade);
|
||||
if (!openOfferManager.findOpenOffer(trade.getId()).isPresent())
|
||||
walletService.swapAnyTradeEntryContextToAvailableEntry(trade.getId());
|
||||
|
|
|
@ -21,9 +21,9 @@ import com.google.inject.Inject;
|
|||
import io.bitsquare.app.DevFlags;
|
||||
import io.bitsquare.app.Log;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.provider.price.PriceFeedService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.TradeWalletService;
|
||||
import io.bitsquare.common.Timer;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.crypto.KeyRing;
|
||||
|
@ -82,7 +82,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||
private final TradeWalletService tradeWalletService;
|
||||
private final OfferBookService offerBookService;
|
||||
private final ClosedTradableManager closedTradableManager;
|
||||
private Preferences preferences;
|
||||
private final Preferences preferences;
|
||||
|
||||
private final TradableList<OpenOffer> openOffers;
|
||||
private final Storage<TradableList<OpenOffer>> openOffersStorage;
|
||||
|
@ -197,7 +197,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||
// BootstrapListener delegate
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void onBootstrapComplete() {
|
||||
private void onBootstrapComplete() {
|
||||
stopped = false;
|
||||
|
||||
// Republish means we send the complete offer object
|
||||
|
@ -546,7 +546,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
|
|||
private void refreshOffer(OpenOffer openOffer) {
|
||||
offerBookService.refreshTTL(openOffer.getOffer(),
|
||||
() -> log.debug("Successful refreshed TTL for offer"),
|
||||
errorMessage -> log.warn(errorMessage));
|
||||
log::warn);
|
||||
}
|
||||
|
||||
private void restart() {
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
package io.bitsquare.trade.protocol.placeoffer;
|
||||
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.TradeWalletService;
|
||||
import io.bitsquare.common.taskrunner.Model;
|
||||
import io.bitsquare.trade.offer.Offer;
|
||||
import io.bitsquare.trade.offer.OfferBookService;
|
||||
|
|
|
@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.placeoffer.tasks;
|
|||
|
||||
import io.bitsquare.arbitration.Arbitrator;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.common.taskrunner.Task;
|
||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||
import io.bitsquare.p2p.NodeAddress;
|
||||
|
@ -35,7 +35,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
public class CreateOfferFeeTx extends Task<PlaceOfferModel> {
|
||||
private static final Logger log = LoggerFactory.getLogger(CreateOfferFeeTx.class);
|
||||
|
||||
public CreateOfferFeeTx(TaskRunner taskHandler, PlaceOfferModel model) {
|
||||
private CreateOfferFeeTx(TaskRunner taskHandler, PlaceOfferModel model) {
|
||||
super(taskHandler, model);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@ package io.bitsquare.trade.protocol.trade;
|
|||
|
||||
import io.bitsquare.app.Version;
|
||||
import io.bitsquare.arbitration.ArbitratorManager;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.data.RawTransactionInput;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.TradeWalletService;
|
||||
import io.bitsquare.common.crypto.KeyRing;
|
||||
import io.bitsquare.common.crypto.PubKeyRing;
|
||||
import io.bitsquare.common.taskrunner.Model;
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
package io.bitsquare.trade.protocol.trade.tasks.buyer;
|
||||
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.data.PreparedDepositTxAndOffererInputs;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.common.crypto.Hash;
|
||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||
import io.bitsquare.trade.Trade;
|
||||
|
@ -33,7 +33,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
public class OffererCreatesAndSignsDepositTxAsBuyer extends TradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(OffererCreatesAndSignsDepositTxAsBuyer.class);
|
||||
|
||||
public OffererCreatesAndSignsDepositTxAsBuyer(TaskRunner taskHandler, Trade trade) {
|
||||
private OffererCreatesAndSignsDepositTxAsBuyer(TaskRunner taskHandler, Trade trade) {
|
||||
super(taskHandler, trade);
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ public class OffererCreatesAndSignsDepositTxAsBuyer extends TradeTask {
|
|||
runInterceptHook();
|
||||
checkNotNull(trade.getTradeAmount(), "trade.getTradeAmount() must not be null");
|
||||
Coin securityDeposit = trade.getOffer().getSecurityDeposit();
|
||||
Coin buyerInputAmount = securityDeposit;
|
||||
@SuppressWarnings("UnnecessaryLocalVariable") Coin buyerInputAmount = securityDeposit;
|
||||
Coin msOutputAmount = buyerInputAmount.add(trade.getTxFee()).add(securityDeposit).add(trade.getTradeAmount());
|
||||
|
||||
log.debug("\n\n------------------------------------------------------------\n"
|
||||
|
|
|
@ -19,8 +19,8 @@ package io.bitsquare.trade.protocol.trade.tasks.buyer;
|
|||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.data.RawTransactionInput;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.common.crypto.Hash;
|
||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||
import io.bitsquare.trade.Trade;
|
||||
|
@ -37,7 +37,7 @@ import java.util.ArrayList;
|
|||
public class SignAndPublishDepositTxAsBuyer extends TradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(SignAndPublishDepositTxAsBuyer.class);
|
||||
|
||||
public SignAndPublishDepositTxAsBuyer(TaskRunner taskHandler, Trade trade) {
|
||||
private SignAndPublishDepositTxAsBuyer(TaskRunner taskHandler, Trade trade) {
|
||||
super(taskHandler, trade);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
package io.bitsquare.trade.protocol.trade.tasks.offerer;
|
||||
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||
import io.bitsquare.trade.OffererTrade;
|
||||
|
@ -42,7 +42,7 @@ public class SetupDepositBalanceListener extends TradeTask {
|
|||
private Subscription tradeStateSubscription;
|
||||
private BalanceListener balanceListener;
|
||||
|
||||
public SetupDepositBalanceListener(TaskRunner taskHandler, Trade trade) {
|
||||
private SetupDepositBalanceListener(TaskRunner taskHandler, Trade trade) {
|
||||
super(taskHandler, trade);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
package io.bitsquare.trade.protocol.trade.tasks.seller;
|
||||
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.data.PreparedDepositTxAndOffererInputs;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.common.crypto.Hash;
|
||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||
import io.bitsquare.trade.Trade;
|
||||
|
@ -33,7 +33,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
public class OffererCreatesAndSignsDepositTxAsSeller extends TradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(OffererCreatesAndSignsDepositTxAsSeller.class);
|
||||
|
||||
public OffererCreatesAndSignsDepositTxAsSeller(TaskRunner taskHandler, Trade trade) {
|
||||
private OffererCreatesAndSignsDepositTxAsSeller(TaskRunner taskHandler, Trade trade) {
|
||||
super(taskHandler, trade);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@ package io.bitsquare.trade.protocol.trade.tasks.seller;
|
|||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.data.RawTransactionInput;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.common.crypto.Hash;
|
||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||
import io.bitsquare.trade.Trade;
|
||||
|
@ -37,7 +37,7 @@ import java.util.ArrayList;
|
|||
public class SignAndPublishDepositTxAsSeller extends TradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(SignAndPublishDepositTxAsSeller.class);
|
||||
|
||||
public SignAndPublishDepositTxAsSeller(TaskRunner taskHandler, Trade trade) {
|
||||
private SignAndPublishDepositTxAsSeller(TaskRunner taskHandler, Trade trade) {
|
||||
super(taskHandler, trade);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.trade.protocol.trade.tasks.seller;
|
||||
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||
import io.bitsquare.trade.Trade;
|
||||
import io.bitsquare.trade.protocol.trade.tasks.TradeTask;
|
||||
|
@ -31,7 +31,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
public class SignPayoutTx extends TradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(SignPayoutTx.class);
|
||||
|
||||
public SignPayoutTx(TaskRunner taskHandler, Trade trade) {
|
||||
private SignPayoutTx(TaskRunner taskHandler, Trade trade) {
|
||||
super(taskHandler, trade);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ package io.bitsquare.trade.protocol.trade.tasks.taker;
|
|||
|
||||
import io.bitsquare.arbitration.Arbitrator;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.common.taskrunner.TaskRunner;
|
||||
import io.bitsquare.p2p.NodeAddress;
|
||||
import io.bitsquare.trade.Trade;
|
||||
|
@ -35,7 +35,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
public class CreateTakeOfferFeeTx extends TradeTask {
|
||||
private static final Logger log = LoggerFactory.getLogger(CreateTakeOfferFeeTx.class);
|
||||
|
||||
public CreateTakeOfferFeeTx(TaskRunner taskHandler, Trade trade) {
|
||||
private CreateTakeOfferFeeTx(TaskRunner taskHandler, Trade trade) {
|
||||
super(taskHandler, trade);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import com.google.inject.Guice;
|
|||
import com.google.inject.Injector;
|
||||
import io.bitsquare.alert.AlertManager;
|
||||
import io.bitsquare.arbitration.ArbitratorManager;
|
||||
import io.bitsquare.btc.*;
|
||||
import io.bitsquare.btc.wallet.*;
|
||||
import io.bitsquare.common.CommonOptionKeys;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
|
@ -209,10 +209,9 @@ public class BitsquareApp extends Application {
|
|||
} else if (new KeyCodeCombination(KeyCode.F, KeyCombination.ALT_DOWN).match(keyEvent)) {
|
||||
showFPSWindow();
|
||||
} else if (new KeyCodeCombination(KeyCode.J, KeyCombination.ALT_DOWN).match(keyEvent)) {
|
||||
BtcWalletService btcWalletService = injector.getInstance(BtcWalletService.class);
|
||||
SquWalletService squWalletService = injector.getInstance(SquWalletService.class);
|
||||
if (btcWalletService.getWallet() != null)
|
||||
new ShowWalletDataWindow(btcWalletService, squWalletService).information("Wallet raw data").show();
|
||||
WalletsManager walletsManager = injector.getInstance(WalletsManager.class);
|
||||
if (walletsManager.areWalletsAvailable())
|
||||
new ShowWalletDataWindow(walletsManager).information("Wallet raw data").show();
|
||||
else
|
||||
new Popup<>().warning("The wallet is not initialized yet").show();
|
||||
} else if (DevFlags.DEV_MODE && new KeyCodeCombination(KeyCode.G, KeyCombination.ALT_DOWN).match(keyEvent)) {
|
||||
|
@ -406,12 +405,12 @@ public class BitsquareApp extends Application {
|
|||
injector.getInstance(TradeManager.class).shutDown();
|
||||
injector.getInstance(OpenOfferManager.class).shutDown(() -> {
|
||||
injector.getInstance(P2PService.class).shutDown(() -> {
|
||||
injector.getInstance(WalletSetup.class).shutDownDone.addListener((ov, o, n) -> {
|
||||
injector.getInstance(WalletsSetup.class).shutDownDone.addListener((ov, o, n) -> {
|
||||
bitsquareAppModule.close(injector);
|
||||
log.debug("Graceful shutdown completed");
|
||||
resultHandler.handleResult();
|
||||
});
|
||||
injector.getInstance(WalletSetup.class).shutDown();
|
||||
injector.getInstance(WalletsSetup.class).shutDown();
|
||||
injector.getInstance(BtcWalletService.class).shutDown();
|
||||
injector.getInstance(SquWalletService.class).shutDown();
|
||||
});
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
package io.bitsquare.gui.components;
|
||||
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.effect.BlurType;
|
||||
|
@ -29,13 +28,7 @@ import org.bitcoinj.core.Coin;
|
|||
|
||||
public class BalanceTextField extends AnchorPane {
|
||||
|
||||
private static BtcWalletService walletService;
|
||||
private Coin targetAmount;
|
||||
|
||||
public static void setWalletService(BtcWalletService walletService) {
|
||||
BalanceTextField.walletService = walletService;
|
||||
}
|
||||
|
||||
private final TextField textField;
|
||||
private final Effect fundedEffect = new DropShadow(BlurType.THREE_PASS_BOX, Color.GREEN, 4, 0.0, 0, 0);
|
||||
private final Effect notFundedEffect = new DropShadow(BlurType.THREE_PASS_BOX, Color.ORANGERED, 4, 0.0, 0, 0);
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
|
||||
package io.bitsquare.gui.components;
|
||||
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.listeners.AddressConfidenceListener;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.gui.components.indicator.TxConfidenceIndicator;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import javafx.scene.control.TextField;
|
||||
|
|
|
@ -19,8 +19,8 @@ package io.bitsquare.gui.components;
|
|||
|
||||
import de.jensd.fx.fontawesome.AwesomeDude;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.listeners.TxConfidenceListener;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.common.util.Utilities;
|
||||
import io.bitsquare.gui.components.indicator.TxConfidenceIndicator;
|
||||
import io.bitsquare.gui.main.overlays.popups.Popup;
|
||||
|
|
|
@ -29,11 +29,14 @@ import io.bitsquare.app.Version;
|
|||
import io.bitsquare.arbitration.ArbitratorManager;
|
||||
import io.bitsquare.arbitration.Dispute;
|
||||
import io.bitsquare.arbitration.DisputeManager;
|
||||
import io.bitsquare.btc.*;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.provider.fee.FeeService;
|
||||
import io.bitsquare.btc.provider.price.MarketPrice;
|
||||
import io.bitsquare.btc.provider.price.PriceFeedService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.WalletsManager;
|
||||
import io.bitsquare.btc.wallet.WalletsSetup;
|
||||
import io.bitsquare.common.Clock;
|
||||
import io.bitsquare.common.Timer;
|
||||
import io.bitsquare.common.UserThread;
|
||||
|
@ -41,7 +44,6 @@ import io.bitsquare.common.crypto.*;
|
|||
import io.bitsquare.filter.FilterManager;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
import io.bitsquare.gui.common.model.ViewModel;
|
||||
import io.bitsquare.gui.components.BalanceTextField;
|
||||
import io.bitsquare.gui.components.BalanceWithConfirmationTextField;
|
||||
import io.bitsquare.gui.components.TxIdTextField;
|
||||
import io.bitsquare.gui.main.overlays.notifications.NotificationCenter;
|
||||
|
@ -78,7 +80,6 @@ import javafx.collections.SetChangeListener;
|
|||
import org.bitcoinj.core.Address;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.bitcoinj.core.Wallet;
|
||||
import org.bitcoinj.store.BlockStoreException;
|
||||
import org.fxmisc.easybind.EasyBind;
|
||||
import org.fxmisc.easybind.Subscription;
|
||||
|
@ -96,14 +97,15 @@ import java.util.stream.Collectors;
|
|||
public class MainViewModel implements ViewModel {
|
||||
private static final Logger log = LoggerFactory.getLogger(MainViewModel.class);
|
||||
|
||||
private final BtcWalletService walletService;
|
||||
private final TradeWalletService tradeWalletService;
|
||||
private final WalletsManager walletsManager;
|
||||
private final WalletsSetup walletsSetup;
|
||||
private final BtcWalletService btcWalletService;
|
||||
private final ArbitratorManager arbitratorManager;
|
||||
private final P2PService p2PService;
|
||||
private final TradeManager tradeManager;
|
||||
private final OpenOfferManager openOfferManager;
|
||||
private final DisputeManager disputeManager;
|
||||
final Preferences preferences;
|
||||
private final Preferences preferences;
|
||||
private final AlertManager alertManager;
|
||||
private final PrivateNotificationManager privateNotificationManager;
|
||||
private final FilterManager filterManager;
|
||||
|
@ -132,7 +134,7 @@ public class MainViewModel implements ViewModel {
|
|||
final StringProperty lockedBalance = new SimpleStringProperty();
|
||||
private MonadicBinding<String> btcInfoBinding;
|
||||
|
||||
final StringProperty marketPrice = new SimpleStringProperty("N/A");
|
||||
private final StringProperty marketPrice = new SimpleStringProperty("N/A");
|
||||
|
||||
// P2P network
|
||||
final StringProperty p2PNetworkInfo = new SimpleStringProperty();
|
||||
|
@ -155,8 +157,6 @@ public class MainViewModel implements ViewModel {
|
|||
final StringProperty p2pNetworkLabelId = new SimpleStringProperty("footer-pane");
|
||||
|
||||
private MonadicBinding<Boolean> allServicesDone, tradesAndUIReady;
|
||||
private WalletSetup walletSetup;
|
||||
private SquWalletService squWalletService;
|
||||
final PriceFeedService priceFeedService;
|
||||
private final User user;
|
||||
private int numBtcPeers = 0;
|
||||
|
@ -176,20 +176,19 @@ public class MainViewModel implements ViewModel {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public MainViewModel(WalletSetup walletSetup, BtcWalletService walletService, TradeWalletService tradeWalletService,
|
||||
SquWalletService squWalletService, PriceFeedService priceFeedService,
|
||||
public MainViewModel(WalletsManager walletsManager, WalletsSetup walletsSetup,
|
||||
BtcWalletService btcWalletService, PriceFeedService priceFeedService,
|
||||
ArbitratorManager arbitratorManager, P2PService p2PService, TradeManager tradeManager,
|
||||
OpenOfferManager openOfferManager, DisputeManager disputeManager, Preferences preferences,
|
||||
User user, AlertManager alertManager, PrivateNotificationManager privateNotificationManager,
|
||||
FilterManager filterManager, WalletPasswordWindow walletPasswordWindow, AddBitcoinNodesWindow addBitcoinNodesWindow,
|
||||
NotificationCenter notificationCenter, TacWindow tacWindow, Clock clock, FeeService feeService,
|
||||
KeyRing keyRing, Navigation navigation, BSFormatter formatter) {
|
||||
this.walletSetup = walletSetup;
|
||||
this.squWalletService = squWalletService; // Add it to get it initiated
|
||||
this.walletsManager = walletsManager;
|
||||
this.walletsSetup = walletsSetup;
|
||||
this.btcWalletService = btcWalletService;
|
||||
this.priceFeedService = priceFeedService;
|
||||
this.user = user;
|
||||
this.walletService = walletService;
|
||||
this.tradeWalletService = tradeWalletService;
|
||||
this.arbitratorManager = arbitratorManager;
|
||||
this.p2PService = p2PService;
|
||||
this.tradeManager = tradeManager;
|
||||
|
@ -213,9 +212,10 @@ public class MainViewModel implements ViewModel {
|
|||
(preferences.getUseTorForBitcoinJ() ? " (using Tor)" : "");
|
||||
|
||||
TxIdTextField.setPreferences(preferences);
|
||||
TxIdTextField.setWalletService(walletService);
|
||||
BalanceTextField.setWalletService(walletService);
|
||||
BalanceWithConfirmationTextField.setWalletService(walletService);
|
||||
|
||||
// TODO
|
||||
TxIdTextField.setWalletService(btcWalletService);
|
||||
BalanceWithConfirmationTextField.setWalletService(btcWalletService);
|
||||
}
|
||||
|
||||
|
||||
|
@ -237,8 +237,7 @@ public class MainViewModel implements ViewModel {
|
|||
|
||||
Timer startupTimeout = UserThread.runAfter(() -> {
|
||||
log.warn("startupTimeout called");
|
||||
Wallet wallet = walletService.getWallet();
|
||||
if (wallet != null && wallet.isEncrypted())
|
||||
if (walletsManager.areWalletsEncrypted())
|
||||
walletInitialized.addListener(walletInitializedListener);
|
||||
else
|
||||
showStartupTimeoutPopup();
|
||||
|
@ -435,7 +434,7 @@ public class MainViewModel implements ViewModel {
|
|||
private void initWalletService() {
|
||||
Log.traceCall();
|
||||
ObjectProperty<Throwable> walletServiceException = new SimpleObjectProperty<>();
|
||||
btcInfoBinding = EasyBind.combine(walletSetup.downloadPercentageProperty(), walletSetup.numPeersProperty(), walletServiceException,
|
||||
btcInfoBinding = EasyBind.combine(walletsSetup.downloadPercentageProperty(), walletsSetup.numPeersProperty(), walletServiceException,
|
||||
(downloadPercentage, numPeers, exception) -> {
|
||||
String result = "";
|
||||
if (exception == null) {
|
||||
|
@ -480,18 +479,18 @@ public class MainViewModel implements ViewModel {
|
|||
btcInfo.set(newValue);
|
||||
});
|
||||
|
||||
walletSetup.initialize(null,
|
||||
walletsSetup.initialize(null, null,
|
||||
() -> {
|
||||
numBtcPeers = walletSetup.numPeersProperty().get();
|
||||
numBtcPeers = walletsSetup.numPeersProperty().get();
|
||||
|
||||
if (walletService.getWallet().isEncrypted()) {
|
||||
// We only check one as we apply encryption to all or none
|
||||
if (walletsManager.areWalletsEncrypted()) {
|
||||
if (p2pNetWorkReady.get())
|
||||
splashP2PNetworkAnimationVisible.set(false);
|
||||
|
||||
walletPasswordWindow
|
||||
.onAesKey(aesKey -> {
|
||||
walletSetup.setAesKey(aesKey);
|
||||
tradeWalletService.setAesKey(aesKey);
|
||||
walletsManager.setAesKey(aesKey);
|
||||
walletInitialized.set(true);
|
||||
})
|
||||
.hideCloseButton()
|
||||
|
@ -529,7 +528,7 @@ public class MainViewModel implements ViewModel {
|
|||
});
|
||||
|
||||
// walletService
|
||||
walletService.addBalanceListener(new BalanceListener() {
|
||||
btcWalletService.addBalanceListener(new BalanceListener() {
|
||||
@Override
|
||||
public void onBalanceChanged(Coin balance, Transaction tx) {
|
||||
updateBalance();
|
||||
|
@ -615,7 +614,7 @@ public class MainViewModel implements ViewModel {
|
|||
|
||||
String remindPasswordAndBackupKey = "remindPasswordAndBackup";
|
||||
user.getPaymentAccountsAsObservable().addListener((SetChangeListener<PaymentAccount>) change -> {
|
||||
if (!walletService.getWallet().isEncrypted() && preferences.showAgain(remindPasswordAndBackupKey) && change.wasAdded()) {
|
||||
if (!walletsManager.areWalletsEncrypted() && 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" +
|
||||
|
@ -747,7 +746,7 @@ public class MainViewModel implements ViewModel {
|
|||
}
|
||||
|
||||
private void setupBtcNumPeersWatcher() {
|
||||
walletSetup.numPeersProperty().addListener((observable, oldValue, newValue) -> {
|
||||
walletsSetup.numPeersProperty().addListener((observable, oldValue, newValue) -> {
|
||||
int numPeers = (int) newValue;
|
||||
if ((int) oldValue > 0 && numPeers == 0) {
|
||||
if (checkNumberOfBtcPeersTimer != null)
|
||||
|
@ -755,7 +754,7 @@ public class MainViewModel implements ViewModel {
|
|||
|
||||
checkNumberOfBtcPeersTimer = UserThread.runAfter(() -> {
|
||||
// check again numPeers
|
||||
if (walletSetup.numPeersProperty().get() == 0) {
|
||||
if (walletsSetup.numPeersProperty().get() == 0) {
|
||||
walletServiceErrorMsg.set("You lost the connection to all bitcoin network peers.\n" +
|
||||
"Maybe you lost your internet connection or your computer was in standby mode.");
|
||||
} else {
|
||||
|
@ -855,7 +854,7 @@ public class MainViewModel implements ViewModel {
|
|||
selectedPriceFeedComboBoxItemProperty.set(itemOptional.get());
|
||||
else
|
||||
findPriceFeedComboBoxItem(preferences.getPreferredTradeCurrency().getCode())
|
||||
.ifPresent(item2 -> selectedPriceFeedComboBoxItemProperty.set(item2));
|
||||
.ifPresent(selectedPriceFeedComboBoxItemProperty::set);
|
||||
|
||||
priceFeedService.setCurrencyCode(item.currencyCode);
|
||||
} else if (item != null) {
|
||||
|
@ -863,7 +862,7 @@ public class MainViewModel implements ViewModel {
|
|||
priceFeedService.setCurrencyCode(item.currencyCode);
|
||||
} else {
|
||||
findPriceFeedComboBoxItem(preferences.getPreferredTradeCurrency().getCode())
|
||||
.ifPresent(item2 -> selectedPriceFeedComboBoxItemProperty.set(item2));
|
||||
.ifPresent(selectedPriceFeedComboBoxItemProperty::set);
|
||||
}
|
||||
|
||||
// Need a delay a bit as we get item.isPriceAvailable() set after that call.
|
||||
|
@ -877,7 +876,7 @@ public class MainViewModel implements ViewModel {
|
|||
}, 100, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
Optional<PriceFeedComboBoxItem> findPriceFeedComboBoxItem(String currencyCode) {
|
||||
private Optional<PriceFeedComboBoxItem> findPriceFeedComboBoxItem(String currencyCode) {
|
||||
return priceFeedComboBoxItems.stream()
|
||||
.filter(item -> item.currencyCode.equals(currencyCode))
|
||||
.findAny();
|
||||
|
@ -904,7 +903,7 @@ public class MainViewModel implements ViewModel {
|
|||
new Popup<>().headLine("Important private notification!")
|
||||
.attention(privateNotification.message)
|
||||
.setHeadlineStyle("-fx-text-fill: -bs-error-red; -fx-font-weight: bold; -fx-font-size: 16;")
|
||||
.onClose(() -> privateNotificationManager.removePrivateNotification())
|
||||
.onClose(privateNotificationManager::removePrivateNotification)
|
||||
.closeButtonText("I understand")
|
||||
.show();
|
||||
}
|
||||
|
@ -912,7 +911,7 @@ 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));
|
||||
.forEach(addressEntry -> btcWalletService.swapTradeEntryToAvailableEntry(addressEntry.getOfferId(), AddressEntry.Context.OFFER_FUNDING));
|
||||
}
|
||||
|
||||
private void updateBalance() {
|
||||
|
@ -927,7 +926,7 @@ public class MainViewModel implements ViewModel {
|
|||
|
||||
private void updateAvailableBalance() {
|
||||
Coin totalAvailableBalance = Coin.valueOf(tradeManager.getAddressEntriesForAvailableBalanceStream()
|
||||
.mapToLong(addressEntry -> walletService.getBalanceForAddress(addressEntry.getAddress()).getValue())
|
||||
.mapToLong(addressEntry -> btcWalletService.getBalanceForAddress(addressEntry.getAddress()).getValue())
|
||||
.sum());
|
||||
availableBalance.set(formatter.formatCoinWithCode(totalAvailableBalance));
|
||||
}
|
||||
|
@ -935,8 +934,8 @@ public class MainViewModel implements ViewModel {
|
|||
private void updateReservedBalance() {
|
||||
Coin sum = Coin.valueOf(openOfferManager.getOpenOffers().stream()
|
||||
.map(openOffer -> {
|
||||
Address address = walletService.getOrCreateAddressEntry(openOffer.getId(), AddressEntry.Context.RESERVED_FOR_TRADE).getAddress();
|
||||
return walletService.getBalanceForAddress(address);
|
||||
Address address = btcWalletService.getOrCreateAddressEntry(openOffer.getId(), AddressEntry.Context.RESERVED_FOR_TRADE).getAddress();
|
||||
return btcWalletService.getBalanceForAddress(address);
|
||||
})
|
||||
.mapToLong(Coin::getValue)
|
||||
.sum());
|
||||
|
@ -947,7 +946,7 @@ public class MainViewModel implements ViewModel {
|
|||
private void updateLockedBalance() {
|
||||
Coin sum = Coin.valueOf(tradeManager.getLockedTradeStream()
|
||||
.mapToLong(trade -> {
|
||||
Coin lockedTradeAmount = walletService.getOrCreateAddressEntry(trade.getId(), AddressEntry.Context.MULTI_SIG).getLockedTradeAmount();
|
||||
Coin lockedTradeAmount = btcWalletService.getOrCreateAddressEntry(trade.getId(), AddressEntry.Context.MULTI_SIG).getLockedTradeAmount();
|
||||
return lockedTradeAmount != null ? lockedTradeAmount.getValue() : 0;
|
||||
})
|
||||
.sum());
|
||||
|
|
|
@ -21,7 +21,7 @@ import com.google.inject.Inject;
|
|||
import io.bitsquare.arbitration.Arbitrator;
|
||||
import io.bitsquare.arbitration.ArbitratorManager;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.common.crypto.KeyRing;
|
||||
import io.bitsquare.common.handlers.ErrorMessageHandler;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
|
@ -42,7 +42,7 @@ import java.util.Date;
|
|||
|
||||
class ArbitratorRegistrationViewModel extends ActivatableViewModel {
|
||||
private final ArbitratorManager arbitratorManager;
|
||||
private User user;
|
||||
private final User user;
|
||||
private final P2PService p2PService;
|
||||
private final BtcWalletService walletService;
|
||||
private final KeyRing keyRing;
|
||||
|
|
|
@ -17,9 +17,7 @@
|
|||
|
||||
package io.bitsquare.gui.main.account.content.password;
|
||||
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.WalletSetup;
|
||||
import io.bitsquare.btc.wallet.WalletsManager;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.common.util.Tuple3;
|
||||
import io.bitsquare.crypto.ScryptUtil;
|
||||
|
@ -36,7 +34,6 @@ import javafx.beans.value.ChangeListener;
|
|||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import org.bitcoinj.core.Wallet;
|
||||
import org.bitcoinj.crypto.KeyCrypterScrypt;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
@ -47,10 +44,8 @@ import static io.bitsquare.gui.util.FormBuilder.*;
|
|||
@FxmlView
|
||||
public class PasswordView extends ActivatableView<GridPane, Void> {
|
||||
|
||||
private final WalletsManager walletsManager;
|
||||
private final PasswordValidator passwordValidator;
|
||||
private final WalletSetup walletSetup;
|
||||
private final BtcWalletService walletService;
|
||||
private final TradeWalletService tradeWalletService;
|
||||
|
||||
private PasswordTextField passwordField;
|
||||
private PasswordTextField repeatedPasswordField;
|
||||
|
@ -67,11 +62,9 @@ public class PasswordView extends ActivatableView<GridPane, Void> {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
private PasswordView(PasswordValidator passwordValidator, WalletSetup walletSetup, BtcWalletService walletService, TradeWalletService tradeWalletService) {
|
||||
private PasswordView(WalletsManager walletsManager, PasswordValidator passwordValidator) {
|
||||
this.walletsManager = walletsManager;
|
||||
this.passwordValidator = passwordValidator;
|
||||
this.walletSetup = walletSetup;
|
||||
this.walletService = walletService;
|
||||
this.tradeWalletService = tradeWalletService;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -103,28 +96,20 @@ public class PasswordView extends ActivatableView<GridPane, Void> {
|
|||
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();
|
||||
|
||||
KeyCrypterScrypt keyCrypterScrypt = walletsManager.getKeyCrypterScrypt();
|
||||
ScryptUtil.deriveKeyWithScrypt(keyCrypterScrypt, password, aesKey -> {
|
||||
deriveStatusLabel.setText("");
|
||||
busyAnimation.stop();
|
||||
|
||||
if (wallet.isEncrypted()) {
|
||||
if (wallet.checkAESKey(aesKey)) {
|
||||
walletSetup.decryptWallets(aesKey);
|
||||
walletService.decryptWallet(aesKey);
|
||||
tradeWalletService.setAesKey(null);
|
||||
if (walletsManager.areWalletsEncrypted()) {
|
||||
if (walletsManager.checkAESKey(aesKey)) {
|
||||
walletsManager.decryptWallets(aesKey);
|
||||
new Popup()
|
||||
.feedback("Wallet successfully decrypted and password protection removed.")
|
||||
.show();
|
||||
passwordField.setText("");
|
||||
repeatedPasswordField.setText("");
|
||||
walletSetup.backupWallets();
|
||||
walletsManager.backupWallets();
|
||||
} else {
|
||||
pwButton.setDisable(false);
|
||||
new Popup()
|
||||
|
@ -133,17 +118,14 @@ public class PasswordView extends ActivatableView<GridPane, Void> {
|
|||
.show();
|
||||
}
|
||||
} else {
|
||||
// we save the key for the trade wallet as we don't require passwords here
|
||||
walletSetup.encryptWallets(keyCrypterScrypt, aesKey);
|
||||
walletService.encryptWallet(keyCrypterScrypt, aesKey);
|
||||
tradeWalletService.setAesKey(aesKey);
|
||||
walletsManager.encryptWallets(keyCrypterScrypt, aesKey);
|
||||
new Popup()
|
||||
.feedback("Wallet successfully encrypted and password protection enabled.")
|
||||
.show();
|
||||
passwordField.setText("");
|
||||
repeatedPasswordField.setText("");
|
||||
walletSetup.clearBackup();
|
||||
walletSetup.backupWallets();
|
||||
walletsManager.clearBackup();
|
||||
walletsManager.backupWallets();
|
||||
}
|
||||
setText();
|
||||
});
|
||||
|
@ -158,7 +140,7 @@ public class PasswordView extends ActivatableView<GridPane, Void> {
|
|||
}
|
||||
|
||||
private void setText() {
|
||||
if (walletService.getWallet().isEncrypted()) {
|
||||
if (walletsManager.areWalletsEncrypted()) {
|
||||
pwButton.setText("Remove password");
|
||||
headline.setText("Remove password protection for wallet");
|
||||
repeatedPasswordField.setVisible(false);
|
||||
|
@ -193,7 +175,7 @@ public class PasswordView extends ActivatableView<GridPane, Void> {
|
|||
passwordValidator.setExternalValidationResult(null);
|
||||
InputValidator.ValidationResult result = passwordValidator.validate(passwordField.getText());
|
||||
if (result.isValid) {
|
||||
if (walletService.getWallet().isEncrypted()) {
|
||||
if (walletsManager.areWalletsEncrypted()) {
|
||||
pwButton.setDisable(false);
|
||||
return;
|
||||
} else {
|
||||
|
|
|
@ -20,7 +20,9 @@ package io.bitsquare.gui.main.account.content.seedwords;
|
|||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import io.bitsquare.app.BitsquareApp;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.SquWalletService;
|
||||
import io.bitsquare.btc.wallet.WalletsManager;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.gui.common.view.ActivatableView;
|
||||
import io.bitsquare.gui.common.view.FxmlView;
|
||||
|
@ -35,8 +37,6 @@ import javafx.scene.control.Button;
|
|||
import javafx.scene.control.DatePicker;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import org.bitcoinj.core.Wallet;
|
||||
import org.bitcoinj.crypto.KeyCrypter;
|
||||
import org.bitcoinj.crypto.MnemonicCode;
|
||||
import org.bitcoinj.crypto.MnemonicException;
|
||||
import org.bitcoinj.wallet.DeterministicSeed;
|
||||
|
@ -54,24 +54,29 @@ import static javafx.beans.binding.Bindings.createBooleanBinding;
|
|||
|
||||
@FxmlView
|
||||
public class SeedWordsView extends ActivatableView<GridPane, Void> {
|
||||
private final BtcWalletService walletService;
|
||||
private final WalletsManager walletsManager;
|
||||
private final BtcWalletService btcWalletService;
|
||||
private final SquWalletService squWalletService;
|
||||
private final WalletPasswordWindow walletPasswordWindow;
|
||||
private Preferences preferences;
|
||||
private final Preferences preferences;
|
||||
|
||||
private Button restoreButton;
|
||||
private TextArea displaySeedWordsTextArea, restoreSeedWordsTextArea;
|
||||
private TextArea displayBtcSeedWordsTextArea, displaySquSeedWordsTextArea, btcSeedWordsTextArea, squSeedWordsTextArea;
|
||||
private DatePicker datePicker, restoreDatePicker;
|
||||
|
||||
private int gridRow = 0;
|
||||
private DeterministicSeed keyChainSeed;
|
||||
private ChangeListener<Boolean> seedWordsValidChangeListener;
|
||||
private SimpleBooleanProperty seedWordsValid = new SimpleBooleanProperty(false);
|
||||
private SimpleBooleanProperty dateValid = new SimpleBooleanProperty(false);
|
||||
private ChangeListener<String> seedWordsTextAreaChangeListener;
|
||||
private ChangeListener<Boolean> btcSeedWordsValidChangeListener, squSeedWordsValidChangeListener;
|
||||
private final SimpleBooleanProperty btcSeedWordsValid = new SimpleBooleanProperty(false);
|
||||
private final SimpleBooleanProperty squSeedWordsValid = new SimpleBooleanProperty(false);
|
||||
private final SimpleBooleanProperty dateValid = new SimpleBooleanProperty(false);
|
||||
private ChangeListener<String> btcSeedWordsTextAreaChangeListener;
|
||||
private ChangeListener<String> squSeedWordsTextAreaChangeListener;
|
||||
private ChangeListener<Boolean> datePickerChangeListener;
|
||||
private ChangeListener<LocalDate> dateChangeListener;
|
||||
private BooleanProperty seedWordsEdited = new SimpleBooleanProperty();
|
||||
private String seedWordText;
|
||||
private final BooleanProperty btcSeedWordsEdited = new SimpleBooleanProperty();
|
||||
private final BooleanProperty squSeedWordsEdited = new SimpleBooleanProperty();
|
||||
private String btcSeedWordText;
|
||||
private String squSeedWordText;
|
||||
private LocalDate walletCreationDate;
|
||||
|
||||
|
||||
|
@ -80,52 +85,80 @@ public class SeedWordsView extends ActivatableView<GridPane, Void> {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
private SeedWordsView(BtcWalletService walletService, WalletPasswordWindow walletPasswordWindow, Preferences preferences) {
|
||||
this.walletService = walletService;
|
||||
private SeedWordsView(WalletsManager walletsManager, BtcWalletService btcWalletService, SquWalletService squWalletService, WalletPasswordWindow walletPasswordWindow, Preferences preferences) {
|
||||
this.walletsManager = walletsManager;
|
||||
this.btcWalletService = btcWalletService;
|
||||
this.squWalletService = squWalletService;
|
||||
this.walletPasswordWindow = walletPasswordWindow;
|
||||
this.preferences = preferences;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
addTitledGroupBg(root, gridRow, 2, "Backup your wallet seed words");
|
||||
displaySeedWordsTextArea = addLabelTextArea(root, gridRow, "Wallet seed words:", "", Layout.FIRST_ROW_DISTANCE).second;
|
||||
displaySeedWordsTextArea.setPrefHeight(60);
|
||||
displaySeedWordsTextArea.setEditable(false);
|
||||
addTitledGroupBg(root, gridRow, 3, "Backup your wallet seed words");
|
||||
displayBtcSeedWordsTextArea = addLabelTextArea(root, gridRow, "BTC wallet seed words:", "", Layout.FIRST_ROW_DISTANCE).second;
|
||||
displayBtcSeedWordsTextArea.setPrefHeight(60);
|
||||
displayBtcSeedWordsTextArea.setEditable(false);
|
||||
|
||||
displaySquSeedWordsTextArea = addLabelTextArea(root, ++gridRow, "SQU wallet seed words:", "").second;
|
||||
displaySquSeedWordsTextArea.setPrefHeight(60);
|
||||
displaySquSeedWordsTextArea.setEditable(false);
|
||||
|
||||
datePicker = addLabelDatePicker(root, ++gridRow, "Wallet Date:").second;
|
||||
datePicker.setMouseTransparent(true);
|
||||
|
||||
addTitledGroupBg(root, ++gridRow, 2, "Restore your wallet seed words", Layout.GROUP_DISTANCE);
|
||||
restoreSeedWordsTextArea = addLabelTextArea(root, gridRow, "Wallet seed words:", "", Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||
restoreSeedWordsTextArea.setPrefHeight(60);
|
||||
addTitledGroupBg(root, ++gridRow, 3, "Restore your wallet seed words", Layout.GROUP_DISTANCE);
|
||||
btcSeedWordsTextArea = addLabelTextArea(root, gridRow, "BTC wallet seed words:", "", Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
|
||||
btcSeedWordsTextArea.setPrefHeight(60);
|
||||
|
||||
squSeedWordsTextArea = addLabelTextArea(root, ++gridRow, "SQU wallet seed words:", "").second;
|
||||
squSeedWordsTextArea.setPrefHeight(60);
|
||||
|
||||
restoreDatePicker = addLabelDatePicker(root, ++gridRow, "Wallet Date:").second;
|
||||
restoreButton = addButtonAfterGroup(root, ++gridRow, "Restore wallet");
|
||||
|
||||
addTitledGroupBg(root, ++gridRow, 1, "Information", Layout.GROUP_DISTANCE);
|
||||
addMultilineLabel(root, gridRow, "Please write down you wallet seed words and the date! " +
|
||||
addMultilineLabel(root, gridRow, "Please write down both wallet seed words and the date! " +
|
||||
"You can recover your wallet any time with those seed words and the date.",
|
||||
Layout.FIRST_ROW_AND_GROUP_DISTANCE);
|
||||
|
||||
|
||||
seedWordsValidChangeListener = (observable, oldValue, newValue) -> {
|
||||
btcSeedWordsValidChangeListener = (observable, oldValue, newValue) -> {
|
||||
if (newValue) {
|
||||
restoreSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
btcSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
} else {
|
||||
restoreSeedWordsTextArea.getStyleClass().add("validation_error");
|
||||
btcSeedWordsTextArea.getStyleClass().add("validation_error");
|
||||
}
|
||||
};
|
||||
|
||||
seedWordsTextAreaChangeListener = (observable, oldValue, newValue) -> {
|
||||
seedWordsEdited.set(true);
|
||||
squSeedWordsValidChangeListener = (observable, oldValue, newValue) -> {
|
||||
if (newValue) {
|
||||
squSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
} else {
|
||||
squSeedWordsTextArea.getStyleClass().add("validation_error");
|
||||
}
|
||||
};
|
||||
|
||||
btcSeedWordsTextAreaChangeListener = (observable, oldValue, newValue) -> {
|
||||
btcSeedWordsEdited.set(true);
|
||||
try {
|
||||
MnemonicCode codec = new MnemonicCode();
|
||||
codec.check(Splitter.on(" ").splitToList(newValue));
|
||||
seedWordsValid.set(true);
|
||||
btcSeedWordsValid.set(true);
|
||||
} catch (IOException | MnemonicException e) {
|
||||
seedWordsValid.set(false);
|
||||
btcSeedWordsValid.set(false);
|
||||
}
|
||||
};
|
||||
|
||||
squSeedWordsTextAreaChangeListener = (observable, oldValue, newValue) -> {
|
||||
squSeedWordsEdited.set(true);
|
||||
try {
|
||||
MnemonicCode codec = new MnemonicCode();
|
||||
codec.check(Splitter.on(" ").splitToList(newValue));
|
||||
squSeedWordsValid.set(true);
|
||||
} catch (IOException | MnemonicException e) {
|
||||
squSeedWordsValid.set(false);
|
||||
}
|
||||
};
|
||||
|
||||
datePickerChangeListener = (observable, oldValue, newValue) -> {
|
||||
if (newValue)
|
||||
|
@ -139,23 +172,27 @@ public class SeedWordsView extends ActivatableView<GridPane, Void> {
|
|||
|
||||
@Override
|
||||
public void activate() {
|
||||
seedWordsValid.addListener(seedWordsValidChangeListener);
|
||||
btcSeedWordsValid.addListener(btcSeedWordsValidChangeListener);
|
||||
squSeedWordsValid.addListener(squSeedWordsValidChangeListener);
|
||||
dateValid.addListener(datePickerChangeListener);
|
||||
restoreSeedWordsTextArea.textProperty().addListener(seedWordsTextAreaChangeListener);
|
||||
btcSeedWordsTextArea.textProperty().addListener(btcSeedWordsTextAreaChangeListener);
|
||||
squSeedWordsTextArea.textProperty().addListener(squSeedWordsTextAreaChangeListener);
|
||||
restoreDatePicker.valueProperty().addListener(dateChangeListener);
|
||||
restoreButton.disableProperty().bind(createBooleanBinding(() -> !seedWordsValid.get() || !dateValid.get() || !seedWordsEdited.get(),
|
||||
seedWordsValid, dateValid, seedWordsEdited));
|
||||
restoreButton.disableProperty().bind(createBooleanBinding(() -> !btcSeedWordsValid.get() || !squSeedWordsValid.get() || !dateValid.get() || !btcSeedWordsEdited.get() || !squSeedWordsEdited.get(),
|
||||
btcSeedWordsValid, squSeedWordsValid, dateValid, btcSeedWordsEdited, squSeedWordsEdited));
|
||||
|
||||
restoreButton.setOnAction(e -> onRestore());
|
||||
|
||||
restoreSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
btcSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
squSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
restoreDatePicker.getStyleClass().remove("validation_error");
|
||||
|
||||
|
||||
DeterministicSeed keyChainSeed = walletService.getWallet().getKeyChainSeed();
|
||||
DeterministicSeed btcKeyChainSeed = btcWalletService.getWallet().getKeyChainSeed();
|
||||
DeterministicSeed squKeyChainSeed = squWalletService.getWallet().getKeyChainSeed();
|
||||
// wallet creation date is not encrypted
|
||||
walletCreationDate = Instant.ofEpochSecond(keyChainSeed.getCreationTimeSeconds()).atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
if (keyChainSeed.isEncrypted()) {
|
||||
walletCreationDate = Instant.ofEpochSecond(walletsManager.getChainSeedCreationTimeSeconds()).atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
if (btcKeyChainSeed.isEncrypted()) {
|
||||
askForPassword();
|
||||
} else {
|
||||
String key = "showSeedWordsWarning";
|
||||
|
@ -165,13 +202,15 @@ public class SeedWordsView extends ActivatableView<GridPane, Void> {
|
|||
.actionButtonText("Yes, and don't ask me again")
|
||||
.onAction(() -> {
|
||||
preferences.dontShowAgain(key, true);
|
||||
initSeedWords(keyChainSeed);
|
||||
initBtcSeedWords(btcKeyChainSeed);
|
||||
initSquSeedWords(squKeyChainSeed);
|
||||
showSeedScreen();
|
||||
})
|
||||
.closeButtonText("No")
|
||||
.show();
|
||||
} else {
|
||||
initSeedWords(keyChainSeed);
|
||||
initBtcSeedWords(btcKeyChainSeed);
|
||||
initSquSeedWords(squKeyChainSeed);
|
||||
showSeedScreen();
|
||||
}
|
||||
}
|
||||
|
@ -179,55 +218,58 @@ public class SeedWordsView extends ActivatableView<GridPane, Void> {
|
|||
|
||||
@Override
|
||||
protected void deactivate() {
|
||||
seedWordsValid.removeListener(seedWordsValidChangeListener);
|
||||
btcSeedWordsValid.removeListener(btcSeedWordsValidChangeListener);
|
||||
squSeedWordsValid.removeListener(squSeedWordsValidChangeListener);
|
||||
dateValid.removeListener(datePickerChangeListener);
|
||||
restoreSeedWordsTextArea.textProperty().removeListener(seedWordsTextAreaChangeListener);
|
||||
btcSeedWordsTextArea.textProperty().removeListener(btcSeedWordsTextAreaChangeListener);
|
||||
squSeedWordsTextArea.textProperty().removeListener(squSeedWordsTextAreaChangeListener);
|
||||
restoreDatePicker.valueProperty().removeListener(dateChangeListener);
|
||||
restoreButton.disableProperty().unbind();
|
||||
|
||||
restoreButton.setOnAction(null);
|
||||
|
||||
|
||||
displaySeedWordsTextArea.setText("");
|
||||
restoreSeedWordsTextArea.setText("");
|
||||
displayBtcSeedWordsTextArea.setText("");
|
||||
displaySquSeedWordsTextArea.setText("");
|
||||
btcSeedWordsTextArea.setText("");
|
||||
squSeedWordsTextArea.setText("");
|
||||
|
||||
restoreDatePicker.setValue(null);
|
||||
datePicker.setValue(null);
|
||||
|
||||
restoreSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
btcSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
squSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
restoreDatePicker.getStyleClass().remove("validation_error");
|
||||
}
|
||||
|
||||
private void askForPassword() {
|
||||
walletPasswordWindow.headLine("Enter password to view seed words").onAesKey(aesKey -> {
|
||||
Wallet wallet = walletService.getWallet();
|
||||
KeyCrypter keyCrypter = wallet.getKeyCrypter();
|
||||
keyChainSeed = wallet.getKeyChainSeed();
|
||||
if (keyCrypter != null) {
|
||||
DeterministicSeed decryptedSeed = keyChainSeed.decrypt(keyCrypter, "", aesKey);
|
||||
initSeedWords(decryptedSeed);
|
||||
showSeedScreen();
|
||||
} else {
|
||||
log.warn("keyCrypter is null");
|
||||
}
|
||||
initBtcSeedWords(walletsManager.getDecryptedSeed(aesKey, btcWalletService.getWallet()));
|
||||
initSquSeedWords(walletsManager.getDecryptedSeed(aesKey, squWalletService.getWallet()));
|
||||
showSeedScreen();
|
||||
}).show();
|
||||
}
|
||||
|
||||
private void initSeedWords(DeterministicSeed seed) {
|
||||
private void initBtcSeedWords(DeterministicSeed seed) {
|
||||
List<String> mnemonicCode = seed.getMnemonicCode();
|
||||
if (mnemonicCode != null) {
|
||||
seedWordText = Joiner.on(" ").join(mnemonicCode);
|
||||
btcSeedWordText = Joiner.on(" ").join(mnemonicCode);
|
||||
}
|
||||
}
|
||||
|
||||
private void initSquSeedWords(DeterministicSeed seed) {
|
||||
List<String> mnemonicCode = seed.getMnemonicCode();
|
||||
if (mnemonicCode != null) {
|
||||
squSeedWordText = Joiner.on(" ").join(mnemonicCode);
|
||||
}
|
||||
}
|
||||
|
||||
private void showSeedScreen() {
|
||||
displaySeedWordsTextArea.setText(seedWordText);
|
||||
displayBtcSeedWordsTextArea.setText(btcSeedWordText);
|
||||
displaySquSeedWordsTextArea.setText(squSeedWordText);
|
||||
datePicker.setValue(walletCreationDate);
|
||||
}
|
||||
|
||||
private void onRestore() {
|
||||
Wallet wallet = walletService.getWallet();
|
||||
if (wallet.getBalance(Wallet.BalanceType.AVAILABLE).value > 0) {
|
||||
if (walletsManager.hasPositiveBalance()) {
|
||||
new Popup()
|
||||
.warning("Your bitcoin wallet is not empty.\n\n" +
|
||||
"You must empty this wallet before attempting to restore an older one, as mixing wallets " +
|
||||
|
@ -237,7 +279,7 @@ public class SeedWordsView extends ActivatableView<GridPane, Void> {
|
|||
"To open that emergency tool press \"cmd + e\".")
|
||||
.actionButtonText("I want to restore anyway")
|
||||
.onAction(this::checkIfEncrypted)
|
||||
.closeButtonText("I will empty my wallet first")
|
||||
.closeButtonText("I will empty my wallets first")
|
||||
.show();
|
||||
} else {
|
||||
checkIfEncrypted();
|
||||
|
@ -245,10 +287,10 @@ public class SeedWordsView extends ActivatableView<GridPane, Void> {
|
|||
}
|
||||
|
||||
private void checkIfEncrypted() {
|
||||
if (walletService.getWallet().isEncrypted()) {
|
||||
if (walletsManager.areWalletsEncrypted()) {
|
||||
new Popup()
|
||||
.information("Your bitcoin wallet is encrypted.\n\n" +
|
||||
"After restore, the wallet will no longer be encrypted and you must set a new password.\n\n" +
|
||||
.information("Your wallets are encrypted.\n\n" +
|
||||
"After restore, the wallets will no longer be encrypted and you must set a new password.\n\n" +
|
||||
"Do you want to proceed?")
|
||||
.closeButtonText("No")
|
||||
.actionButtonText("Yes")
|
||||
|
@ -261,13 +303,16 @@ public class SeedWordsView extends ActivatableView<GridPane, Void> {
|
|||
|
||||
private void doRestore() {
|
||||
long date = restoreDatePicker.getValue().atStartOfDay().toEpochSecond(ZoneOffset.UTC);
|
||||
DeterministicSeed seed = new DeterministicSeed(Splitter.on(" ").splitToList(restoreSeedWordsTextArea.getText()), null, "", date);
|
||||
walletService.restoreSeedWords(seed,
|
||||
DeterministicSeed btcSeed = new DeterministicSeed(Splitter.on(" ").splitToList(btcSeedWordsTextArea.getText()), null, "", date);
|
||||
DeterministicSeed squSeed = new DeterministicSeed(Splitter.on(" ").splitToList(squSeedWordsTextArea.getText()), null, "", date);
|
||||
walletsManager.restoreSeedWords(
|
||||
btcSeed,
|
||||
squSeed,
|
||||
() -> UserThread.execute(() -> {
|
||||
log.info("Wallet restored with seed words");
|
||||
log.info("Wallets restored with seed words");
|
||||
|
||||
new Popup()
|
||||
.feedback("Wallet restored successfully with the new seed words.\n\n" +
|
||||
.feedback("Wallets restored successfully with the new seed words.\n\n" +
|
||||
"You need to shut down and restart the application.")
|
||||
.closeButtonText("Shut down")
|
||||
.onClose(BitsquareApp.shutDownHandler::run).show();
|
||||
|
@ -275,7 +320,7 @@ public class SeedWordsView extends ActivatableView<GridPane, Void> {
|
|||
throwable -> UserThread.execute(() -> {
|
||||
log.error(throwable.getMessage());
|
||||
new Popup()
|
||||
.error("An error occurred when restoring the wallet with seed words.\n" +
|
||||
.error("An error occurred when restoring the wallets with seed words.\n" +
|
||||
"Error message: " + throwable.getMessage())
|
||||
.show();
|
||||
}));
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
package io.bitsquare.gui.main.dao.wallet.dashboard;
|
||||
|
||||
import io.bitsquare.btc.SquWalletService;
|
||||
import io.bitsquare.btc.wallet.SquWalletService;
|
||||
import io.bitsquare.gui.common.view.ActivatableView;
|
||||
import io.bitsquare.gui.common.view.FxmlView;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
|
@ -44,7 +44,7 @@ public class TokenDashboardView extends ActivatableView<GridPane, Void> {
|
|||
|
||||
@Nullable
|
||||
private Wallet squWallet;
|
||||
private int gridRow = 0;
|
||||
private final int gridRow = 0;
|
||||
private WalletEventListener walletEventListener;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -115,7 +115,8 @@ public class TokenDashboardView extends ActivatableView<GridPane, Void> {
|
|||
}
|
||||
|
||||
private void updateBalance() {
|
||||
confirmedBalance.setText(formatter.formatCoinWithCode(squWallet.getBalance()));
|
||||
if (squWallet != null)
|
||||
confirmedBalance.setText(formatter.formatCoinWithCode(squWallet.getBalance()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package io.bitsquare.gui.main.dao.wallet.receive;
|
||||
|
||||
import io.bitsquare.app.DevFlags;
|
||||
import io.bitsquare.btc.SquWalletService;
|
||||
import io.bitsquare.btc.wallet.SquWalletService;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.gui.common.view.ActivatableView;
|
||||
import io.bitsquare.gui.common.view.FxmlView;
|
||||
|
@ -194,7 +194,8 @@ public class TokenReceiveView extends ActivatableView<GridPane, Void> {
|
|||
}
|
||||
|
||||
private void updateBalance() {
|
||||
confirmedBalance.setText(formatter.formatCoinWithCode(squWallet.getBalance()));
|
||||
if (squWallet != null)
|
||||
confirmedBalance.setText(formatter.formatCoinWithCode(squWallet.getBalance()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,14 +19,12 @@ package io.bitsquare.gui.main.dao.wallet.send;
|
|||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import io.bitsquare.app.DevFlags;
|
||||
import io.bitsquare.btc.AddressEntryException;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.InsufficientFundsException;
|
||||
import io.bitsquare.btc.SquWalletService;
|
||||
import io.bitsquare.btc.exceptions.SigningException;
|
||||
import io.bitsquare.btc.exceptions.TransactionVerificationException;
|
||||
import io.bitsquare.btc.exceptions.WalletException;
|
||||
import io.bitsquare.btc.provider.fee.FeeService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.SquWalletService;
|
||||
import io.bitsquare.gui.common.view.ActivatableView;
|
||||
import io.bitsquare.gui.common.view.FxmlView;
|
||||
import io.bitsquare.gui.components.InputTextField;
|
||||
|
@ -39,6 +37,7 @@ import javafx.scene.control.TextField;
|
|||
import javafx.scene.layout.GridPane;
|
||||
import org.bitcoinj.core.*;
|
||||
import org.bitcoinj.script.Script;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
@ -54,8 +53,8 @@ public class TokenSendView extends ActivatableView<GridPane, Void> {
|
|||
private TextField confirmedBalance;
|
||||
|
||||
private final SquWalletService squWalletService;
|
||||
private BtcWalletService btcWalletService;
|
||||
private FeeService feeService;
|
||||
private final BtcWalletService btcWalletService;
|
||||
private final FeeService feeService;
|
||||
private final BSFormatter formatter;
|
||||
|
||||
@Nullable
|
||||
|
@ -103,10 +102,9 @@ public class TokenSendView extends ActivatableView<GridPane, Void> {
|
|||
Coin receiverAmount = formatter.parseToCoin(amountInputTextField.getText());
|
||||
Optional<String> changeAddressStringOptional = Optional.empty();
|
||||
try {
|
||||
Transaction preparedSquTx = squWalletService.prepareSendTx(receiversAddressString, receiverAmount, changeAddressStringOptional);
|
||||
Transaction preparedMixedTx = btcWalletService.getTransactionWithFeeInput(preparedSquTx);
|
||||
Transaction signedMixedTx = squWalletService.signFinalSendTx(preparedMixedTx);
|
||||
squWalletService.commitAndBroadcastTx(signedMixedTx, new FutureCallback<Transaction>() {
|
||||
Transaction preparedSendTx = squWalletService.getPreparedSendTx(receiversAddressString, receiverAmount, changeAddressStringOptional);
|
||||
Transaction txWithBtcFee = btcWalletService.addFeeInputToPreparedSquSendTx(preparedSendTx);
|
||||
squWalletService.signAndBroadcastSendTx(txWithBtcFee, new FutureCallback<Transaction>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable Transaction result) {
|
||||
if (result != null) {
|
||||
|
@ -117,12 +115,12 @@ public class TokenSendView extends ActivatableView<GridPane, Void> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
public void onFailure(@NotNull Throwable t) {
|
||||
log.error(t.toString());
|
||||
new Popup<>().warning(t.toString());
|
||||
}
|
||||
});
|
||||
} catch (AddressFormatException | AddressEntryException | SigningException | InsufficientFundsException |
|
||||
} catch (AddressFormatException | InsufficientFundsException |
|
||||
TransactionVerificationException | WalletException | InsufficientMoneyException e) {
|
||||
log.error(e.toString());
|
||||
e.printStackTrace();
|
||||
|
@ -183,7 +181,8 @@ public class TokenSendView extends ActivatableView<GridPane, Void> {
|
|||
}
|
||||
|
||||
private void updateBalance() {
|
||||
confirmedBalance.setText(formatter.formatCoinWithCode(squWallet.getBalance()));
|
||||
if (squWallet != null)
|
||||
confirmedBalance.setText(formatter.formatCoinWithCode(squWallet.getBalance()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
package io.bitsquare.gui.main.funds.deposit;
|
||||
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.listeners.TxConfidenceListener;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.gui.components.indicator.TxConfidenceIndicator;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
|
@ -33,7 +33,7 @@ import org.bitcoinj.core.TransactionConfidence;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class DepositListItem {
|
||||
class DepositListItem {
|
||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final StringProperty balance = new SimpleStringProperty();
|
||||
|
@ -41,7 +41,7 @@ public class DepositListItem {
|
|||
private Coin balanceAsCoin;
|
||||
private final TxConfidenceIndicator txConfidenceIndicator;
|
||||
private final Tooltip tooltip;
|
||||
private String addressString;
|
||||
private final String addressString;
|
||||
private String usage = "-";
|
||||
private TxConfidenceListener txConfidenceListener;
|
||||
private int numTxOutputs = 0;
|
||||
|
|
|
@ -20,9 +20,9 @@ package io.bitsquare.gui.main.funds.deposit;
|
|||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import io.bitsquare.app.DevFlags;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.provider.fee.FeeService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.gui.common.view.ActivatableView;
|
||||
|
@ -83,7 +83,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
|||
private InputTextField amountTextField;
|
||||
|
||||
private final BtcWalletService walletService;
|
||||
private FeeService feeService;
|
||||
private final FeeService feeService;
|
||||
private final BSFormatter formatter;
|
||||
private final Preferences preferences;
|
||||
private final String paymentLabelString;
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
package io.bitsquare.gui.main.funds.locked;
|
||||
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.trade.Tradable;
|
||||
import io.bitsquare.trade.Trade;
|
||||
|
@ -32,7 +32,7 @@ import org.bitcoinj.core.Transaction;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class LockedListItem {
|
||||
class LockedListItem {
|
||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final StringProperty date = new SimpleStringProperty();
|
||||
|
|
|
@ -19,8 +19,8 @@ package io.bitsquare.gui.main.funds.locked;
|
|||
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.gui.common.view.ActivatableView;
|
||||
import io.bitsquare.gui.common.view.FxmlView;
|
||||
import io.bitsquare.gui.components.HyperlinkWithIcon;
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
package io.bitsquare.gui.main.funds.reserved;
|
||||
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.trade.Tradable;
|
||||
import io.bitsquare.trade.offer.OpenOffer;
|
||||
|
@ -32,7 +32,7 @@ import org.bitcoinj.core.Transaction;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class ReservedListItem {
|
||||
class ReservedListItem {
|
||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private final StringProperty date = new SimpleStringProperty();
|
||||
|
|
|
@ -19,8 +19,8 @@ package io.bitsquare.gui.main.funds.reserved;
|
|||
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.gui.common.view.ActivatableView;
|
||||
import io.bitsquare.gui.common.view.FxmlView;
|
||||
import io.bitsquare.gui.components.HyperlinkWithIcon;
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
package io.bitsquare.gui.main.funds.transactions;
|
||||
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.listeners.TxConfidenceListener;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.gui.components.indicator.TxConfidenceIndicator;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import io.bitsquare.trade.Tradable;
|
||||
|
@ -33,7 +33,7 @@ import javax.annotation.Nullable;
|
|||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
|
||||
public class TransactionsListItem {
|
||||
class TransactionsListItem {
|
||||
private final Logger log = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private String dateString;
|
||||
|
@ -69,7 +69,7 @@ public class TransactionsListItem {
|
|||
|
||||
Coin valueSentToMe = transaction.getValueSentToMe(walletService.getWallet());
|
||||
Coin valueSentFromMe = transaction.getValueSentFromMe(walletService.getWallet());
|
||||
Address address = null;
|
||||
Address address;
|
||||
if (valueSentToMe.isZero()) {
|
||||
amountAsCoin = valueSentFromMe.multiply(-1);
|
||||
|
||||
|
@ -186,29 +186,27 @@ public class TransactionsListItem {
|
|||
|
||||
private void updateConfidence(TransactionConfidence confidence) {
|
||||
confirmations = confidence.getDepthInBlocks();
|
||||
if (confidence != null) {
|
||||
switch (confidence.getConfidenceType()) {
|
||||
case UNKNOWN:
|
||||
tooltip.setText("Unknown transaction status");
|
||||
txConfidenceIndicator.setProgress(0);
|
||||
break;
|
||||
case PENDING:
|
||||
tooltip.setText("Seen by " + confidence.numBroadcastPeers() + " peer(s) / 0 confirmations");
|
||||
txConfidenceIndicator.setProgress(-1.0);
|
||||
break;
|
||||
case BUILDING:
|
||||
tooltip.setText("Confirmed in " + confidence.getDepthInBlocks() + " block(s)");
|
||||
txConfidenceIndicator.setProgress(Math.min(1, (double) confidence.getDepthInBlocks() / 6.0));
|
||||
break;
|
||||
case DEAD:
|
||||
tooltip.setText("Transaction is invalid.");
|
||||
txConfidenceIndicator.setStyle(" -fx-progress-color: -bs-error-red;");
|
||||
txConfidenceIndicator.setProgress(-1);
|
||||
break;
|
||||
}
|
||||
|
||||
txConfidenceIndicator.setPrefSize(24, 24);
|
||||
switch (confidence.getConfidenceType()) {
|
||||
case UNKNOWN:
|
||||
tooltip.setText("Unknown transaction status");
|
||||
txConfidenceIndicator.setProgress(0);
|
||||
break;
|
||||
case PENDING:
|
||||
tooltip.setText("Seen by " + confidence.numBroadcastPeers() + " peer(s) / 0 confirmations");
|
||||
txConfidenceIndicator.setProgress(-1.0);
|
||||
break;
|
||||
case BUILDING:
|
||||
tooltip.setText("Confirmed in " + confidence.getDepthInBlocks() + " block(s)");
|
||||
txConfidenceIndicator.setProgress(Math.min(1, (double) confidence.getDepthInBlocks() / 6.0));
|
||||
break;
|
||||
case DEAD:
|
||||
tooltip.setText("Transaction is invalid.");
|
||||
txConfidenceIndicator.setStyle(" -fx-progress-color: -bs-error-red;");
|
||||
txConfidenceIndicator.setProgress(-1);
|
||||
break;
|
||||
}
|
||||
|
||||
txConfidenceIndicator.setPrefSize(24, 24);
|
||||
}
|
||||
|
||||
public TxConfidenceIndicator getTxConfidenceIndicator() {
|
||||
|
|
|
@ -20,7 +20,7 @@ package io.bitsquare.gui.main.funds.transactions;
|
|||
import com.googlecode.jcsv.writer.CSVEntryConverter;
|
||||
import de.jensd.fx.fontawesome.AwesomeIcon;
|
||||
import io.bitsquare.arbitration.DisputeManager;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.common.util.Tuple4;
|
||||
import io.bitsquare.common.util.Utilities;
|
||||
|
@ -88,7 +88,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||
private final Preferences preferences;
|
||||
private final TradeDetailsWindow tradeDetailsWindow;
|
||||
private final DisputeManager disputeManager;
|
||||
private Stage stage;
|
||||
private final Stage stage;
|
||||
private final OfferDetailsWindow offerDetailsWindow;
|
||||
private WalletEventListener walletEventListener;
|
||||
private EventHandler<KeyEvent> keyEventEventHandler;
|
||||
|
@ -564,9 +564,7 @@ public class TransactionsView extends ActivatableView<VBox, Void> {
|
|||
walletService.swapAnyTradeEntryContextToAvailableEntry(tradable.getId());
|
||||
|
||||
new Popup().information("Transaction successfully sent to a new address in the local Bitsquare wallet.").show();
|
||||
}, errorMessage -> {
|
||||
new Popup().warning(errorMessage).show();
|
||||
});
|
||||
}, errorMessage -> new Popup().warning(errorMessage).show());
|
||||
} catch (Throwable e) {
|
||||
new Popup().warning(e.getMessage()).show();
|
||||
}
|
||||
|
|
|
@ -18,15 +18,15 @@
|
|||
package io.bitsquare.gui.main.funds.withdrawal;
|
||||
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.gui.util.BSFormatter;
|
||||
import javafx.scene.control.Label;
|
||||
import org.bitcoinj.core.Address;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
|
||||
public class WithdrawalListItem {
|
||||
class WithdrawalListItem {
|
||||
private final BalanceListener balanceListener;
|
||||
private final Label balanceLabel;
|
||||
private final AddressEntry addressEntry;
|
||||
|
@ -83,12 +83,12 @@ public class WithdrawalListItem {
|
|||
|
||||
WithdrawalListItem that = (WithdrawalListItem) o;
|
||||
|
||||
return !(addressEntry != null ? !addressEntry.equals(that.addressEntry) : that.addressEntry != null);
|
||||
return addressEntry.equals(that.addressEntry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return addressEntry != null ? addressEntry.hashCode() : 0;
|
||||
return addressEntry.hashCode();
|
||||
}
|
||||
|
||||
private Address getAddress() {
|
||||
|
|
|
@ -22,10 +22,10 @@ import de.jensd.fx.fontawesome.AwesomeIcon;
|
|||
import io.bitsquare.app.DevFlags;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.AddressEntryException;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.InsufficientFundsException;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.provider.fee.FeeService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.util.MathUtils;
|
||||
import io.bitsquare.gui.common.view.ActivatableView;
|
||||
|
@ -90,7 +90,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
|
|||
private BalanceListener balanceListener;
|
||||
private Set<String> fromAddresses;
|
||||
private Coin amountOfSelectedItems = Coin.ZERO;
|
||||
private ObjectProperty<Coin> senderAmountAsCoinProperty = new SimpleObjectProperty<>(Coin.ZERO);
|
||||
private final ObjectProperty<Coin> senderAmountAsCoinProperty = new SimpleObjectProperty<>(Coin.ZERO);
|
||||
private ChangeListener<String> amountListener;
|
||||
private ChangeListener<Boolean> amountFocusListener;
|
||||
|
||||
|
|
|
@ -22,12 +22,12 @@ import io.bitsquare.app.DevFlags;
|
|||
import io.bitsquare.app.Version;
|
||||
import io.bitsquare.arbitration.Arbitrator;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.blockchain.BlockchainService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.provider.fee.FeeService;
|
||||
import io.bitsquare.btc.provider.price.PriceFeedService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.TradeWalletService;
|
||||
import io.bitsquare.common.crypto.KeyRing;
|
||||
import io.bitsquare.gui.Navigation;
|
||||
import io.bitsquare.gui.common.model.ActivatableDataModel;
|
||||
|
@ -63,8 +63,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
*/
|
||||
class CreateOfferDataModel extends ActivatableDataModel {
|
||||
private final OpenOfferManager openOfferManager;
|
||||
final BtcWalletService walletService;
|
||||
final TradeWalletService tradeWalletService;
|
||||
private final BtcWalletService walletService;
|
||||
private final TradeWalletService tradeWalletService;
|
||||
private final Preferences preferences;
|
||||
private final User user;
|
||||
private final KeyRing keyRing;
|
||||
|
@ -79,7 +79,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
|||
private final AddressEntry addressEntry;
|
||||
private Coin createOfferFeeAsCoin;
|
||||
private Coin txFeeAsCoin;
|
||||
private Coin securityDepositAsCoin;
|
||||
private final Coin securityDepositAsCoin;
|
||||
private final BalanceListener balanceListener;
|
||||
private final SetChangeListener<PaymentAccount> paymentAccountsChangeListener;
|
||||
|
||||
|
@ -111,7 +111,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
|||
PaymentAccount paymentAccount;
|
||||
boolean isTabSelected;
|
||||
private Notification walletFundedNotification;
|
||||
boolean useSavingsWallet;
|
||||
private boolean useSavingsWallet;
|
||||
Coin totalAvailableBalance;
|
||||
private double marketPriceMargin = 0;
|
||||
|
||||
|
@ -400,13 +400,9 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
|||
Optional<TradeCurrency> tradeCurrencyOptional = preferences.getTradeCurrenciesAsObservable().stream().filter(e -> e.getCode().equals(code)).findAny();
|
||||
if (!tradeCurrencyOptional.isPresent()) {
|
||||
if (CurrencyUtil.isCryptoCurrency(code)) {
|
||||
CurrencyUtil.getCryptoCurrency(code).ifPresent(cryptoCurrency -> {
|
||||
preferences.addCryptoCurrency(cryptoCurrency);
|
||||
});
|
||||
CurrencyUtil.getCryptoCurrency(code).ifPresent(preferences::addCryptoCurrency);
|
||||
} else {
|
||||
CurrencyUtil.getFiatCurrency(code).ifPresent(fiatCurrency -> {
|
||||
preferences.addFiatCurrency(fiatCurrency);
|
||||
});
|
||||
CurrencyUtil.getFiatCurrency(code).ifPresent(preferences::addFiatCurrency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -526,7 +522,7 @@ class CreateOfferDataModel extends ActivatableDataModel {
|
|||
}
|
||||
}
|
||||
|
||||
void updateBalance() {
|
||||
private void updateBalance() {
|
||||
Coin tradeWalletBalance = walletService.getBalanceForAddress(addressEntry.getAddress());
|
||||
if (useSavingsWallet) {
|
||||
Coin savingWalletBalance = walletService.getSavingWalletBalance();
|
||||
|
|
|
@ -21,12 +21,12 @@ import com.google.inject.Inject;
|
|||
import io.bitsquare.app.DevFlags;
|
||||
import io.bitsquare.arbitration.Arbitrator;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.blockchain.BlockchainService;
|
||||
import io.bitsquare.btc.listeners.BalanceListener;
|
||||
import io.bitsquare.btc.provider.fee.FeeService;
|
||||
import io.bitsquare.btc.provider.price.PriceFeedService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.TradeWalletService;
|
||||
import io.bitsquare.gui.common.model.ActivatableDataModel;
|
||||
import io.bitsquare.gui.main.overlays.notifications.Notification;
|
||||
import io.bitsquare.gui.main.overlays.popups.Popup;
|
||||
|
@ -59,8 +59,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
*/
|
||||
class TakeOfferDataModel extends ActivatableDataModel {
|
||||
private final TradeManager tradeManager;
|
||||
final TradeWalletService tradeWalletService;
|
||||
final BtcWalletService walletService;
|
||||
private final TradeWalletService tradeWalletService;
|
||||
private final BtcWalletService walletService;
|
||||
private final User user;
|
||||
private final FeeService feeService;
|
||||
private final Preferences preferences;
|
||||
|
@ -88,9 +88,9 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
|||
final ObjectProperty<Coin> missingCoin = new SimpleObjectProperty<>(Coin.ZERO);
|
||||
|
||||
private BalanceListener balanceListener;
|
||||
PaymentAccount paymentAccount;
|
||||
private PaymentAccount paymentAccount;
|
||||
private boolean isTabSelected;
|
||||
boolean useSavingsWallet;
|
||||
private boolean useSavingsWallet;
|
||||
Coin totalAvailableBalance;
|
||||
private Notification walletFundedNotification;
|
||||
Fiat tradePrice;
|
||||
|
@ -367,7 +367,7 @@ class TakeOfferDataModel extends ActivatableDataModel {
|
|||
}
|
||||
}
|
||||
|
||||
void updateBalance() {
|
||||
private void updateBalance() {
|
||||
Coin tradeWalletBalance = walletService.getBalanceForAddress(addressEntry.getAddress());
|
||||
if (useSavingsWallet) {
|
||||
Coin savingWalletBalance = walletService.getSavingWalletBalance();
|
||||
|
|
|
@ -21,9 +21,9 @@ import io.bitsquare.arbitration.Dispute;
|
|||
import io.bitsquare.arbitration.DisputeManager;
|
||||
import io.bitsquare.arbitration.DisputeResult;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.exceptions.TransactionVerificationException;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.TradeWalletService;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.gui.components.InputTextField;
|
||||
|
@ -93,7 +93,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
|||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Inject
|
||||
public DisputeSummaryWindow(BSFormatter formatter, DisputeManager disputeManager, BtcWalletService walletService, TradeWalletService tradeWalletService) {
|
||||
private DisputeSummaryWindow(BSFormatter formatter, DisputeManager disputeManager, BtcWalletService walletService, TradeWalletService tradeWalletService) {
|
||||
this.formatter = formatter;
|
||||
this.disputeManager = disputeManager;
|
||||
this.walletService = walletService;
|
||||
|
@ -638,7 +638,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
|||
|
||||
hide();
|
||||
|
||||
finalizeDisputeHandlerOptional.ifPresent(finalizeDisputeHandler -> finalizeDisputeHandler.run());
|
||||
finalizeDisputeHandlerOptional.ifPresent(Runnable::run);
|
||||
} catch (AddressFormatException | TransactionVerificationException e2) {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ package io.bitsquare.gui.main.overlays.windows;
|
|||
|
||||
import io.bitsquare.app.DevFlags;
|
||||
import io.bitsquare.btc.Restrictions;
|
||||
import io.bitsquare.btc.WalletService;
|
||||
import io.bitsquare.btc.wallet.WalletService;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.gui.components.InputTextField;
|
||||
|
@ -160,9 +160,7 @@ public class EmptyWalletWindow extends Overlay<EmptyWalletWindow> {
|
|||
new Popup().warning("You have open offers which will be removed if you empty the wallet.\n" +
|
||||
"Are you sure that you want to empty your wallet?")
|
||||
.actionButtonText("Yes, I am sure")
|
||||
.onAction(() -> {
|
||||
doEmptyWallet2(aesKey);
|
||||
})
|
||||
.onAction(() -> doEmptyWallet2(aesKey))
|
||||
.show(), 300, TimeUnit.MILLISECONDS);
|
||||
} else {
|
||||
doEmptyWallet2(aesKey);
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
|
||||
package io.bitsquare.gui.main.overlays.windows;
|
||||
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.SquWalletService;
|
||||
import io.bitsquare.btc.wallet.WalletsManager;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.common.util.Utilities;
|
||||
import io.bitsquare.gui.main.overlays.Overlay;
|
||||
|
@ -35,17 +34,15 @@ import static io.bitsquare.gui.util.FormBuilder.addLabelTextArea;
|
|||
|
||||
public class ShowWalletDataWindow extends Overlay<ShowWalletDataWindow> {
|
||||
private static final Logger log = LoggerFactory.getLogger(ShowWalletDataWindow.class);
|
||||
private BtcWalletService btcWalletService;
|
||||
private SquWalletService squWalletService;
|
||||
private final WalletsManager walletsManager;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Public API
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public ShowWalletDataWindow(BtcWalletService btcWalletService, SquWalletService squWalletService) {
|
||||
this.btcWalletService = btcWalletService;
|
||||
this.squWalletService = squWalletService;
|
||||
public ShowWalletDataWindow(WalletsManager walletsManager) {
|
||||
this.walletsManager = walletsManager;
|
||||
type = Type.Attention;
|
||||
}
|
||||
|
||||
|
@ -98,9 +95,7 @@ public class ShowWalletDataWindow extends Overlay<ShowWalletDataWindow> {
|
|||
onAction(() -> Utilities.copyToClipboard(textArea.getText()));
|
||||
}
|
||||
|
||||
private void showWallet(TextArea textArea, CheckBox isUpdateCheckBox) {
|
||||
String btcWalletData = btcWalletService.exportWalletData(isUpdateCheckBox.isSelected());
|
||||
String sqrWalletData = squWalletService.exportWalletData(isUpdateCheckBox.isSelected());
|
||||
textArea.setText("BTC Wallet:\n" + btcWalletData + "\n\nSQU Wallet:\n" + sqrWalletData);
|
||||
private void showWallet(TextArea textArea, CheckBox includePrivKeysCheckBox) {
|
||||
textArea.setText(walletsManager.getWalletsAsString(includePrivKeysCheckBox.isSelected()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
package io.bitsquare.gui.main.overlays.windows;
|
||||
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.exceptions.TransactionVerificationException;
|
||||
import io.bitsquare.btc.exceptions.WalletException;
|
||||
import io.bitsquare.btc.wallet.TradeWalletService;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.gui.components.InputTextField;
|
||||
import io.bitsquare.gui.main.overlays.Overlay;
|
||||
|
@ -30,6 +30,7 @@ import javafx.scene.input.KeyCode;
|
|||
import org.bitcoinj.core.AddressFormatException;
|
||||
import org.bitcoinj.core.Coin;
|
||||
import org.bitcoinj.core.Transaction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -42,7 +43,7 @@ import static io.bitsquare.gui.util.FormBuilder.addLabelInputTextField;
|
|||
|
||||
public class SpendFromDepositTxWindow extends Overlay<SpendFromDepositTxWindow> {
|
||||
private static final Logger log = LoggerFactory.getLogger(SpendFromDepositTxWindow.class);
|
||||
private TradeWalletService tradeWalletService;
|
||||
private final TradeWalletService tradeWalletService;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -159,7 +160,7 @@ public class SpendFromDepositTxWindow extends Overlay<SpendFromDepositTxWindow>
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
public void onFailure(@NotNull Throwable t) {
|
||||
log.error(t.toString());
|
||||
log.error("onFailure");
|
||||
UserThread.execute(() -> new Popup<>().warning(t.toString()).show());
|
||||
|
|
|
@ -19,7 +19,7 @@ package io.bitsquare.gui.main.overlays.windows;
|
|||
|
||||
import com.google.common.base.Splitter;
|
||||
import io.bitsquare.app.BitsquareApp;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.WalletsManager;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.util.Tuple2;
|
||||
import io.bitsquare.crypto.ScryptUtil;
|
||||
|
@ -44,7 +44,6 @@ import javafx.scene.layout.ColumnConstraints;
|
|||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import org.bitcoinj.core.Wallet;
|
||||
import org.bitcoinj.crypto.KeyCrypterScrypt;
|
||||
import org.bitcoinj.crypto.MnemonicCode;
|
||||
import org.bitcoinj.crypto.MnemonicException;
|
||||
|
@ -67,23 +66,25 @@ import static javafx.beans.binding.Bindings.createBooleanBinding;
|
|||
|
||||
public class WalletPasswordWindow extends Overlay<WalletPasswordWindow> {
|
||||
private static final Logger log = LoggerFactory.getLogger(WalletPasswordWindow.class);
|
||||
private final BtcWalletService walletService;
|
||||
private Button unlockButton;
|
||||
private AesKeyHandler aesKeyHandler;
|
||||
private PasswordTextField passwordTextField;
|
||||
private Button forgotPasswordButton;
|
||||
private Button restoreButton;
|
||||
private TextArea restoreSeedWordsTextArea;
|
||||
private TextArea btcSeedWordsTextArea, squSeedWordsTextArea;
|
||||
private DatePicker restoreDatePicker;
|
||||
private SimpleBooleanProperty seedWordsValid = new SimpleBooleanProperty(false);
|
||||
private SimpleBooleanProperty dateValid = new SimpleBooleanProperty(false);
|
||||
private BooleanProperty seedWordsEdited = new SimpleBooleanProperty();
|
||||
private final SimpleBooleanProperty btcSeedWordsValid = new SimpleBooleanProperty(false);
|
||||
private final SimpleBooleanProperty squSeedWordsValid = new SimpleBooleanProperty(false);
|
||||
private final SimpleBooleanProperty dateValid = new SimpleBooleanProperty(false);
|
||||
private final BooleanProperty btcSeedWordsEdited = new SimpleBooleanProperty();
|
||||
private final BooleanProperty squSeedWordsEdited = new SimpleBooleanProperty();
|
||||
private ChangeListener<String> changeListener;
|
||||
private ChangeListener<String> seedWordsTextAreaChangeListener;
|
||||
private ChangeListener<String> btcWordsTextAreaChangeListener, squWordsTextAreaChangeListener;
|
||||
private ChangeListener<Boolean> datePickerChangeListener;
|
||||
private ChangeListener<Boolean> seedWordsValidChangeListener;
|
||||
private ChangeListener<LocalDate> dateChangeListener;
|
||||
private LocalDate walletCreationDate;
|
||||
private final WalletsManager walletsManager;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -95,8 +96,8 @@ public class WalletPasswordWindow extends Overlay<WalletPasswordWindow> {
|
|||
}
|
||||
|
||||
@Inject
|
||||
public WalletPasswordWindow(BtcWalletService walletService) {
|
||||
this.walletService = walletService;
|
||||
private WalletPasswordWindow(WalletsManager walletsManager) {
|
||||
this.walletsManager = walletsManager;
|
||||
type = Type.Attention;
|
||||
width = 800;
|
||||
}
|
||||
|
@ -136,15 +137,18 @@ public class WalletPasswordWindow extends Overlay<WalletPasswordWindow> {
|
|||
passwordTextField.textProperty().removeListener(changeListener);
|
||||
|
||||
if (seedWordsValidChangeListener != null) {
|
||||
seedWordsValid.removeListener(seedWordsValidChangeListener);
|
||||
btcSeedWordsValid.removeListener(seedWordsValidChangeListener);
|
||||
dateValid.removeListener(datePickerChangeListener);
|
||||
restoreSeedWordsTextArea.textProperty().removeListener(seedWordsTextAreaChangeListener);
|
||||
btcSeedWordsTextArea.textProperty().removeListener(btcWordsTextAreaChangeListener);
|
||||
squSeedWordsTextArea.textProperty().removeListener(squWordsTextAreaChangeListener);
|
||||
restoreDatePicker.valueProperty().removeListener(dateChangeListener);
|
||||
restoreButton.disableProperty().unbind();
|
||||
restoreButton.setOnAction(null);
|
||||
restoreSeedWordsTextArea.setText("");
|
||||
btcSeedWordsTextArea.setText("");
|
||||
squSeedWordsTextArea.setText("");
|
||||
restoreDatePicker.setValue(null);
|
||||
restoreSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
btcSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
squSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
restoreDatePicker.getStyleClass().remove("validation_error");
|
||||
}
|
||||
}
|
||||
|
@ -193,13 +197,12 @@ public class WalletPasswordWindow extends Overlay<WalletPasswordWindow> {
|
|||
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();
|
||||
KeyCrypterScrypt keyCrypterScrypt = walletsManager.getKeyCrypterScrypt();
|
||||
if (keyCrypterScrypt != null) {
|
||||
busyAnimation.play();
|
||||
deriveStatusLabel.setText("Derive key from password");
|
||||
ScryptUtil.deriveKeyWithScrypt(keyCrypterScrypt, password, aesKey -> {
|
||||
if (wallet.checkAESKey(aesKey)) {
|
||||
if (walletsManager.checkAESKey(aesKey)) {
|
||||
if (aesKeyHandler != null)
|
||||
aesKeyHandler.onAesKey(aesKey);
|
||||
|
||||
|
@ -229,7 +232,7 @@ public class WalletPasswordWindow extends Overlay<WalletPasswordWindow> {
|
|||
Button cancelButton = new Button("Cancel");
|
||||
cancelButton.setOnAction(event -> {
|
||||
hide();
|
||||
closeHandlerOptional.ifPresent(closeHandler -> closeHandler.run());
|
||||
closeHandlerOptional.ifPresent(Runnable::run);
|
||||
});
|
||||
|
||||
HBox hBox = new HBox();
|
||||
|
@ -273,41 +276,56 @@ public class WalletPasswordWindow extends Overlay<WalletPasswordWindow> {
|
|||
|
||||
gridPane.getChildren().add(separator);
|
||||
|
||||
Tuple2<Label, TextArea> tuple = addLabelTextArea(gridPane, ++rowIndex, "Wallet seed words:", "", 5);
|
||||
restoreSeedWordsTextArea = tuple.second;
|
||||
restoreSeedWordsTextArea.setPrefHeight(60);
|
||||
restoreSeedWordsTextArea.setStyle("-fx-border-color: #ddd;");
|
||||
Tuple2<Label, TextArea> tuple = addLabelTextArea(gridPane, ++rowIndex, "BTC wallet seed words:", "", 5);
|
||||
btcSeedWordsTextArea = tuple.second;
|
||||
btcSeedWordsTextArea.setPrefHeight(60);
|
||||
btcSeedWordsTextArea.setStyle("-fx-border-color: #ddd;");
|
||||
|
||||
Tuple2<Label, TextArea> tuple2 = addLabelTextArea(gridPane, ++rowIndex, "SQU wallet seed words:", "", 5);
|
||||
squSeedWordsTextArea = tuple2.second;
|
||||
squSeedWordsTextArea.setPrefHeight(60);
|
||||
squSeedWordsTextArea.setStyle("-fx-border-color: #ddd;");
|
||||
|
||||
Tuple2<Label, DatePicker> labelDatePickerTuple2 = addLabelDatePicker(gridPane, ++rowIndex, "Creation Date:");
|
||||
restoreDatePicker = labelDatePickerTuple2.second;
|
||||
restoreButton = addButton(gridPane, ++rowIndex, "Restore wallet");
|
||||
restoreButton = addButton(gridPane, ++rowIndex, "Restore wallets");
|
||||
restoreButton.setDefaultButton(true);
|
||||
stage.setHeight(340);
|
||||
|
||||
DeterministicSeed keyChainSeed = walletService.getWallet().getKeyChainSeed();
|
||||
|
||||
// wallet creation date is not encrypted
|
||||
walletCreationDate = Instant.ofEpochSecond(keyChainSeed.getCreationTimeSeconds()).atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
walletCreationDate = Instant.ofEpochSecond(walletsManager.getChainSeedCreationTimeSeconds()).atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
|
||||
|
||||
restoreButton.disableProperty().bind(createBooleanBinding(() -> !seedWordsValid.get() || !dateValid.get() || !seedWordsEdited.get(),
|
||||
seedWordsValid, dateValid, seedWordsEdited));
|
||||
restoreButton.disableProperty().bind(createBooleanBinding(() -> !btcSeedWordsValid.get() || !dateValid.get() || !btcSeedWordsEdited.get(),
|
||||
btcSeedWordsValid, dateValid, btcSeedWordsEdited));
|
||||
|
||||
|
||||
seedWordsValidChangeListener = (observable, oldValue, newValue) -> {
|
||||
if (newValue) {
|
||||
restoreSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
btcSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
} else {
|
||||
restoreSeedWordsTextArea.getStyleClass().add("validation_error");
|
||||
btcSeedWordsTextArea.getStyleClass().add("validation_error");
|
||||
}
|
||||
};
|
||||
|
||||
seedWordsTextAreaChangeListener = (observable, oldValue, newValue) -> {
|
||||
seedWordsEdited.set(true);
|
||||
btcWordsTextAreaChangeListener = (observable, oldValue, newValue) -> {
|
||||
btcSeedWordsEdited.set(true);
|
||||
try {
|
||||
MnemonicCode codec = new MnemonicCode();
|
||||
codec.check(Splitter.on(" ").splitToList(newValue));
|
||||
seedWordsValid.set(true);
|
||||
btcSeedWordsValid.set(true);
|
||||
} catch (IOException | MnemonicException e) {
|
||||
seedWordsValid.set(false);
|
||||
btcSeedWordsValid.set(false);
|
||||
}
|
||||
};
|
||||
squWordsTextAreaChangeListener = (observable, oldValue, newValue) -> {
|
||||
squSeedWordsEdited.set(true);
|
||||
try {
|
||||
MnemonicCode codec = new MnemonicCode();
|
||||
codec.check(Splitter.on(" ").splitToList(newValue));
|
||||
squSeedWordsValid.set(true);
|
||||
} catch (IOException | MnemonicException e) {
|
||||
squSeedWordsValid.set(false);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -318,28 +336,27 @@ public class WalletPasswordWindow extends Overlay<WalletPasswordWindow> {
|
|||
else
|
||||
restoreDatePicker.getStyleClass().add("validation_error");
|
||||
};
|
||||
dateChangeListener = (observable, oldValue, newValue) -> {
|
||||
dateValid.set(walletCreationDate.equals(newValue));
|
||||
};
|
||||
dateChangeListener = (observable, oldValue, newValue) -> dateValid.set(walletCreationDate.equals(newValue));
|
||||
|
||||
seedWordsValid.addListener(seedWordsValidChangeListener);
|
||||
btcSeedWordsValid.addListener(seedWordsValidChangeListener);
|
||||
dateValid.addListener(datePickerChangeListener);
|
||||
restoreSeedWordsTextArea.textProperty().addListener(seedWordsTextAreaChangeListener);
|
||||
btcSeedWordsTextArea.textProperty().addListener(btcWordsTextAreaChangeListener);
|
||||
squSeedWordsTextArea.textProperty().addListener(squWordsTextAreaChangeListener);
|
||||
restoreDatePicker.valueProperty().addListener(dateChangeListener);
|
||||
restoreButton.disableProperty().bind(createBooleanBinding(() -> !seedWordsValid.get() || !dateValid.get() || !seedWordsEdited.get(),
|
||||
seedWordsValid, dateValid, seedWordsEdited));
|
||||
restoreButton.disableProperty().bind(createBooleanBinding(() -> !btcSeedWordsValid.get() || !dateValid.get() || !btcSeedWordsEdited.get(),
|
||||
btcSeedWordsValid, dateValid, btcSeedWordsEdited));
|
||||
|
||||
restoreButton.setOnAction(e -> onRestore());
|
||||
|
||||
restoreSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
btcSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
squSeedWordsTextArea.getStyleClass().remove("validation_error");
|
||||
restoreDatePicker.getStyleClass().remove("validation_error");
|
||||
|
||||
layout();
|
||||
}
|
||||
|
||||
private void onRestore() {
|
||||
Wallet wallet = walletService.getWallet();
|
||||
if (wallet.getBalance(Wallet.BalanceType.AVAILABLE).value > 0) {
|
||||
if (walletsManager.hasPositiveBalance()) {
|
||||
new Popup()
|
||||
.warning("Your bitcoin wallet is not empty.\n\n" +
|
||||
"You must empty this wallet before attempting to restore an older one, as mixing wallets " +
|
||||
|
@ -357,7 +374,7 @@ public class WalletPasswordWindow extends Overlay<WalletPasswordWindow> {
|
|||
}
|
||||
|
||||
private void checkIfEncrypted() {
|
||||
if (walletService.getWallet().isEncrypted()) {
|
||||
if (walletsManager.areWalletsEncrypted()) {
|
||||
new Popup()
|
||||
.information("Your bitcoin wallet is encrypted.\n\n" +
|
||||
"After restore, the wallet will no longer be encrypted and you must set a new password.\n\n" +
|
||||
|
@ -373,8 +390,11 @@ public class WalletPasswordWindow extends Overlay<WalletPasswordWindow> {
|
|||
|
||||
private void doRestore() {
|
||||
long date = restoreDatePicker.getValue().atStartOfDay().toEpochSecond(ZoneOffset.UTC);
|
||||
DeterministicSeed seed = new DeterministicSeed(Splitter.on(" ").splitToList(restoreSeedWordsTextArea.getText()), null, "", date);
|
||||
walletService.restoreSeedWords(seed,
|
||||
DeterministicSeed btcSeed = new DeterministicSeed(Splitter.on(" ").splitToList(btcSeedWordsTextArea.getText()), null, "", date);
|
||||
DeterministicSeed squSeed = new DeterministicSeed(Splitter.on(" ").splitToList(squSeedWordsTextArea.getText()), null, "", date);
|
||||
walletsManager.restoreSeedWords(
|
||||
btcSeed,
|
||||
squSeed,
|
||||
() -> UserThread.execute(() -> {
|
||||
log.debug("Wallet restored with seed words");
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ import io.bitsquare.app.Log;
|
|||
import io.bitsquare.arbitration.Arbitrator;
|
||||
import io.bitsquare.arbitration.Dispute;
|
||||
import io.bitsquare.arbitration.DisputeManager;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.TradeWalletService;
|
||||
import io.bitsquare.btc.provider.fee.FeeService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.TradeWalletService;
|
||||
import io.bitsquare.common.crypto.KeyRing;
|
||||
import io.bitsquare.common.handlers.ErrorMessageHandler;
|
||||
import io.bitsquare.common.handlers.FaultHandler;
|
||||
|
@ -70,11 +70,11 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
|||
public final TradeManager tradeManager;
|
||||
public final BtcWalletService walletService;
|
||||
private final TradeWalletService tradeWalletService;
|
||||
private FeeService feeService;
|
||||
private final FeeService feeService;
|
||||
private final User user;
|
||||
private final KeyRing keyRing;
|
||||
public final DisputeManager disputeManager;
|
||||
private P2PService p2PService;
|
||||
private final P2PService p2PService;
|
||||
public final Navigation navigation;
|
||||
public final WalletPasswordWindow walletPasswordWindow;
|
||||
private final NotificationCenter notificationCenter;
|
||||
|
@ -213,7 +213,7 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
|||
return tradeManager.isMyOffer(offer);
|
||||
}
|
||||
|
||||
boolean isOfferer() {
|
||||
private boolean isOfferer() {
|
||||
return isOfferer;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,11 @@ package io.bitsquare.gui.main.portfolio.pendingtrades.steps.buyer;
|
|||
|
||||
import io.bitsquare.app.DevFlags;
|
||||
import io.bitsquare.app.Log;
|
||||
import io.bitsquare.btc.*;
|
||||
import io.bitsquare.btc.AddressEntry;
|
||||
import io.bitsquare.btc.AddressEntryException;
|
||||
import io.bitsquare.btc.InsufficientFundsException;
|
||||
import io.bitsquare.btc.Restrictions;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.FaultHandler;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
|
@ -54,8 +58,8 @@ import static io.bitsquare.gui.util.FormBuilder.*;
|
|||
public class BuyerStep5View extends TradeStepView {
|
||||
private final ChangeListener<Boolean> focusedPropertyListener;
|
||||
|
||||
protected Label btcTradeAmountLabel;
|
||||
protected Label fiatTradeAmountLabel;
|
||||
private Label btcTradeAmountLabel;
|
||||
private Label fiatTradeAmountLabel;
|
||||
private InputTextField withdrawAddressTextField;
|
||||
private Button withdrawToExternalWalletButton, useSavingsWalletButton;
|
||||
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
package io.bitsquare.gui.main.settings.network;
|
||||
|
||||
import io.bitsquare.app.BitsquareApp;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.WalletSetup;
|
||||
import io.bitsquare.btc.wallet.WalletsSetup;
|
||||
import io.bitsquare.common.Clock;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.gui.common.model.Activatable;
|
||||
|
@ -68,26 +67,24 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
|
|||
TableColumn<P2pNetworkListItem, String> onionAddressColumn, connectionTypeColumn, creationDateColumn,
|
||||
roundTripTimeColumn, sentBytesColumn, receivedBytesColumn, peerTypeColumn;
|
||||
|
||||
private final BtcWalletService walletService;
|
||||
private final Preferences preferences;
|
||||
private Clock clock;
|
||||
private final Clock clock;
|
||||
private final BSFormatter formatter;
|
||||
private final WalletSetup walletSetup;
|
||||
private final WalletsSetup walletsSetup;
|
||||
private final P2PService p2PService;
|
||||
private Subscription numP2PPeersSubscription;
|
||||
private Subscription bitcoinPeersSubscription;
|
||||
private Subscription nodeAddressSubscription;
|
||||
private ObservableList<P2pNetworkListItem> networkListItems = FXCollections.observableArrayList();
|
||||
private final ObservableList<P2pNetworkListItem> networkListItems = FXCollections.observableArrayList();
|
||||
private final SortedList<P2pNetworkListItem> sortedList = new SortedList<>(networkListItems);
|
||||
private ChangeListener<Boolean> btcNodesFocusListener;
|
||||
private String btcNodesPreFocusText;
|
||||
|
||||
@Inject
|
||||
public NetworkSettingsView(BtcWalletService walletService, WalletSetup walletSetup, P2PService p2PService, Preferences preferences, Clock clock,
|
||||
public NetworkSettingsView(WalletsSetup walletsSetup, P2PService p2PService, Preferences preferences, Clock clock,
|
||||
BSFormatter formatter) {
|
||||
super();
|
||||
this.walletService = walletService;
|
||||
this.walletSetup = walletSetup;
|
||||
this.walletsSetup = walletsSetup;
|
||||
this.p2PService = p2PService;
|
||||
this.preferences = preferences;
|
||||
this.clock = clock;
|
||||
|
@ -137,7 +134,7 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
|
|||
}
|
||||
});
|
||||
|
||||
bitcoinPeersSubscription = EasyBind.subscribe(walletSetup.connectedPeersProperty(), connectedPeers -> updateBitcoinPeersTextArea());
|
||||
bitcoinPeersSubscription = EasyBind.subscribe(walletsSetup.connectedPeersProperty(), connectedPeers -> updateBitcoinPeersTextArea());
|
||||
|
||||
nodeAddressSubscription = EasyBind.subscribe(p2PService.getNetworkNode().nodeAddressProperty(),
|
||||
nodeAddress -> onionAddress.setText(nodeAddress == null ? "Not known yet..." : p2PService.getAddress().getFullAddress()));
|
||||
|
@ -204,7 +201,7 @@ public class NetworkSettingsView extends ActivatableViewAndModel<GridPane, Activ
|
|||
|
||||
private void updateBitcoinPeersTextArea() {
|
||||
bitcoinPeersTextArea.clear();
|
||||
List<Peer> peerList = walletSetup.connectedPeersProperty().get();
|
||||
List<Peer> peerList = walletsSetup.connectedPeersProperty().get();
|
||||
if (peerList != null) {
|
||||
peerList.stream().forEach(e -> {
|
||||
if (bitcoinPeersTextArea.getText().length() > 0)
|
||||
|
|
|
@ -27,9 +27,9 @@ public class SQUFormatter extends BSFormatter {
|
|||
private static final Logger log = LoggerFactory.getLogger(SQUFormatter.class);
|
||||
|
||||
@Inject
|
||||
public SQUFormatter() {
|
||||
private SQUFormatter() {
|
||||
super();
|
||||
coinFormat = new MonetaryFormat().shift(8).minDecimals(0).repeatOptionalDecimals(0, 0);
|
||||
coinFormat = new MonetaryFormat().shift(5).minDecimals(0).code(5, "SQU").minDecimals(3);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ import io.bitsquare.app.BitsquareEnvironment;
|
|||
import io.bitsquare.app.Log;
|
||||
import io.bitsquare.app.Version;
|
||||
import io.bitsquare.arbitration.ArbitratorManager;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.SquWalletService;
|
||||
import io.bitsquare.btc.WalletSetup;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.SquWalletService;
|
||||
import io.bitsquare.btc.wallet.WalletsSetup;
|
||||
import io.bitsquare.common.CommonOptionKeys;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
|
@ -39,7 +39,7 @@ public class Headless {
|
|||
private final OpenOfferManager openOfferManager;
|
||||
private final HeadlessModule headlessModule;
|
||||
|
||||
private P2PService p2pService;
|
||||
private final P2PService p2pService;
|
||||
|
||||
public static void setEnvironment(Environment env) {
|
||||
Headless.env = env;
|
||||
|
@ -137,12 +137,12 @@ public class Headless {
|
|||
injector.getInstance(ArbitratorManager.class).shutDown();
|
||||
injector.getInstance(OpenOfferManager.class).shutDown(() -> {
|
||||
injector.getInstance(P2PService.class).shutDown(() -> {
|
||||
injector.getInstance(WalletSetup.class).shutDownDone.addListener((ov, o, n) -> {
|
||||
injector.getInstance(WalletsSetup.class).shutDownDone.addListener((ov, o, n) -> {
|
||||
headlessModule.close(injector);
|
||||
log.debug("Graceful shutdown completed");
|
||||
resultHandler.handleResult();
|
||||
});
|
||||
injector.getInstance(WalletSetup.class).shutDown();
|
||||
injector.getInstance(WalletsSetup.class).shutDown();
|
||||
injector.getInstance(BtcWalletService.class).shutDown();
|
||||
injector.getInstance(SquWalletService.class).shutDown();
|
||||
});
|
||||
|
|
|
@ -8,9 +8,9 @@ import io.bitsquare.app.BitsquareEnvironment;
|
|||
import io.bitsquare.app.Log;
|
||||
import io.bitsquare.app.Version;
|
||||
import io.bitsquare.arbitration.ArbitratorManager;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.SquWalletService;
|
||||
import io.bitsquare.btc.WalletSetup;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.SquWalletService;
|
||||
import io.bitsquare.btc.wallet.WalletsSetup;
|
||||
import io.bitsquare.common.CommonOptionKeys;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
|
@ -40,7 +40,7 @@ public class Monitor {
|
|||
private final OpenOfferManager openOfferManager;
|
||||
private final MonitorModule monitorModule;
|
||||
|
||||
private P2PService p2pService;
|
||||
private final P2PService p2pService;
|
||||
|
||||
public static void setEnvironment(Environment env) {
|
||||
Monitor.env = env;
|
||||
|
@ -140,12 +140,12 @@ public class Monitor {
|
|||
injector.getInstance(ArbitratorManager.class).shutDown();
|
||||
injector.getInstance(OpenOfferManager.class).shutDown(() -> {
|
||||
injector.getInstance(P2PService.class).shutDown(() -> {
|
||||
injector.getInstance(WalletSetup.class).shutDownDone.addListener((ov, o, n) -> {
|
||||
injector.getInstance(WalletsSetup.class).shutDownDone.addListener((ov, o, n) -> {
|
||||
monitorModule.close(injector);
|
||||
log.debug("Graceful shutdown completed");
|
||||
resultHandler.handleResult();
|
||||
});
|
||||
injector.getInstance(WalletSetup.class).shutDown();
|
||||
injector.getInstance(WalletsSetup.class).shutDown();
|
||||
injector.getInstance(BtcWalletService.class).shutDown();
|
||||
injector.getInstance(SquWalletService.class).shutDown();
|
||||
});
|
||||
|
|
|
@ -8,9 +8,9 @@ import io.bitsquare.app.BitsquareEnvironment;
|
|||
import io.bitsquare.app.Log;
|
||||
import io.bitsquare.app.Version;
|
||||
import io.bitsquare.arbitration.ArbitratorManager;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.SquWalletService;
|
||||
import io.bitsquare.btc.WalletSetup;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.SquWalletService;
|
||||
import io.bitsquare.btc.wallet.WalletsSetup;
|
||||
import io.bitsquare.common.CommonOptionKeys;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
|
@ -38,7 +38,7 @@ public class SeedNode {
|
|||
private final SeedNodeModule seedNodeModule;
|
||||
private final TradeStatisticsManager tradeStatisticsManager;
|
||||
|
||||
private P2PService p2pService;
|
||||
private final P2PService p2pService;
|
||||
|
||||
public static void setEnvironment(Environment env) {
|
||||
SeedNode.env = env;
|
||||
|
@ -92,7 +92,7 @@ public class SeedNode {
|
|||
tradeStatisticsManager = injector.getInstance(TradeStatisticsManager.class);
|
||||
}
|
||||
|
||||
public void shutDown() {
|
||||
private void shutDown() {
|
||||
gracefulShutDown(() -> {
|
||||
log.debug("Shutdown complete");
|
||||
System.exit(0);
|
||||
|
@ -106,12 +106,12 @@ public class SeedNode {
|
|||
injector.getInstance(ArbitratorManager.class).shutDown();
|
||||
injector.getInstance(OpenOfferManager.class).shutDown(() -> {
|
||||
injector.getInstance(P2PService.class).shutDown(() -> {
|
||||
injector.getInstance(WalletSetup.class).shutDownDone.addListener((ov, o, n) -> {
|
||||
injector.getInstance(WalletsSetup.class).shutDownDone.addListener((ov, o, n) -> {
|
||||
seedNodeModule.close(injector);
|
||||
log.debug("Graceful shutdown completed");
|
||||
resultHandler.handleResult();
|
||||
});
|
||||
injector.getInstance(WalletSetup.class).shutDown();
|
||||
injector.getInstance(WalletsSetup.class).shutDown();
|
||||
injector.getInstance(BtcWalletService.class).shutDown();
|
||||
injector.getInstance(SquWalletService.class).shutDown();
|
||||
});
|
||||
|
|
|
@ -8,10 +8,10 @@ import io.bitsquare.app.BitsquareEnvironment;
|
|||
import io.bitsquare.app.Log;
|
||||
import io.bitsquare.app.Version;
|
||||
import io.bitsquare.arbitration.ArbitratorManager;
|
||||
import io.bitsquare.btc.BtcWalletService;
|
||||
import io.bitsquare.btc.SquWalletService;
|
||||
import io.bitsquare.btc.WalletSetup;
|
||||
import io.bitsquare.btc.provider.price.PriceFeedService;
|
||||
import io.bitsquare.btc.wallet.BtcWalletService;
|
||||
import io.bitsquare.btc.wallet.SquWalletService;
|
||||
import io.bitsquare.btc.wallet.WalletsSetup;
|
||||
import io.bitsquare.common.CommonOptionKeys;
|
||||
import io.bitsquare.common.UserThread;
|
||||
import io.bitsquare.common.handlers.ResultHandler;
|
||||
|
@ -43,7 +43,7 @@ public class Statistics {
|
|||
private final OfferBookService offerBookService;
|
||||
private final PriceFeedService priceFeedService;
|
||||
|
||||
private P2PService p2pService;
|
||||
private final P2PService p2pService;
|
||||
|
||||
public static void setEnvironment(Environment env) {
|
||||
Statistics.env = env;
|
||||
|
@ -105,7 +105,7 @@ public class Statistics {
|
|||
(errorMessage, throwable) -> log.warn(throwable.getMessage()));
|
||||
}
|
||||
|
||||
public void shutDown() {
|
||||
private void shutDown() {
|
||||
gracefulShutDown(() -> {
|
||||
log.debug("Shutdown complete");
|
||||
System.exit(0);
|
||||
|
@ -119,12 +119,12 @@ public class Statistics {
|
|||
injector.getInstance(ArbitratorManager.class).shutDown();
|
||||
injector.getInstance(OpenOfferManager.class).shutDown(() -> {
|
||||
injector.getInstance(P2PService.class).shutDown(() -> {
|
||||
injector.getInstance(WalletSetup.class).shutDownDone.addListener((ov, o, n) -> {
|
||||
injector.getInstance(WalletsSetup.class).shutDownDone.addListener((ov, o, n) -> {
|
||||
statisticsModule.close(injector);
|
||||
log.debug("Graceful shutdown completed");
|
||||
resultHandler.handleResult();
|
||||
});
|
||||
injector.getInstance(WalletSetup.class).shutDown();
|
||||
injector.getInstance(WalletsSetup.class).shutDown();
|
||||
injector.getInstance(BtcWalletService.class).shutDown();
|
||||
injector.getInstance(SquWalletService.class).shutDown();
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue