diff --git a/core/src/main/java/com/google/bitcoin/core/Wallet.java b/core/src/main/java/com/google/bitcoin/core/Wallet.java
index 56dc0f1d..744f517b 100644
--- a/core/src/main/java/com/google/bitcoin/core/Wallet.java
+++ b/core/src/main/java/com/google/bitcoin/core/Wallet.java
@@ -19,6 +19,7 @@ package com.google.bitcoin.core;
import com.google.bitcoin.crypto.KeyCrypterScrypt;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.SettableFuture;
import org.bitcoinj.wallet.Protos.Wallet.EncryptionType;
import org.spongycastle.crypto.params.KeyParameter;
@@ -2807,6 +2808,45 @@ public class Wallet implements Serializable, BlockChainListener {
setCoinSelector(Wallet.AllowUnconfirmedCoinSelector.get());
}
+ /**
+ * Returns a future that will complete when the balance of the given type is equal or larger to the given value.
+ * If the wallet already has a large enough balance the future is returned in a pre-completed state. Note that this
+ * method is not blocking, if you want to actually wait immediately, you have to call .get() on the result.
+ */
+ public ListenableFuture waitForBalance(final BigInteger value, final BalanceType type) {
+ final SettableFuture future = SettableFuture.create();
+ final BigInteger current = getBalance(type);
+ if (current.compareTo(value) >= 0) {
+ // Already have enough.
+ future.set(current);
+ return future;
+ }
+ addEventListener(new AbstractWalletEventListener() {
+ private boolean done = false;
+
+ @Override
+ public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx) {
+ check();
+ }
+
+ private void check() {
+ final BigInteger newBalance = getBalance(type);
+ if (!done && newBalance.compareTo(value) >= 0) {
+ // Have enough now.
+ done = true;
+ removeEventListener(this);
+ future.set(newBalance);
+ }
+ }
+
+ @Override
+ public void onCoinsReceived(Wallet w, Transaction t, BigInteger b1, BigInteger b2) {
+ check();
+ }
+ });
+ return future;
+ }
+
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Boilerplate for running event listeners - unlocks the wallet, runs, re-locks.
diff --git a/core/src/test/java/com/google/bitcoin/core/WalletTest.java b/core/src/test/java/com/google/bitcoin/core/WalletTest.java
index 38ff9668..640fac21 100644
--- a/core/src/test/java/com/google/bitcoin/core/WalletTest.java
+++ b/core/src/test/java/com/google/bitcoin/core/WalletTest.java
@@ -22,6 +22,7 @@ import com.google.bitcoin.crypto.KeyCrypter;
import com.google.bitcoin.crypto.KeyCrypterException;
import com.google.bitcoin.crypto.KeyCrypterScrypt;
import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.ListenableFuture;
import com.google.protobuf.ByteString;
import org.bitcoinj.wallet.Protos;
@@ -175,9 +176,15 @@ public class WalletTest extends TestWithWallet {
private void receiveAPendingTransaction(Wallet wallet, Address toAddress) throws Exception {
BigInteger v1 = Utils.toNanoCoins(1, 0);
+ final ListenableFuture availFuture = wallet.waitForBalance(v1, Wallet.BalanceType.AVAILABLE);
+ final ListenableFuture estimatedFuture = wallet.waitForBalance(v1, Wallet.BalanceType.ESTIMATED);
+ assertFalse(availFuture.isDone());
+ assertFalse(estimatedFuture.isDone());
Transaction t1 = sendMoneyToWallet(wallet, v1, toAddress, null);
assertEquals(BigInteger.ZERO, wallet.getBalance());
assertEquals(v1, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
+ assertFalse(availFuture.isDone());
+ assertTrue(estimatedFuture.isDone());
assertEquals(1, wallet.getPoolSize(Pool.PENDING));
assertEquals(0, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
sendMoneyToWallet(wallet, t1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
@@ -185,6 +192,8 @@ public class WalletTest extends TestWithWallet {
assertEquals("Incorrect confirmed tx PENDING pool size", 0, wallet.getPoolSize(WalletTransaction.Pool.PENDING));
assertEquals("Incorrect confirmed tx UNSPENT pool size", 1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
assertEquals("Incorrect confirmed tx ALL pool size", 1, wallet.getPoolSize(WalletTransaction.Pool.ALL));
+ assertTrue(availFuture.isDone());
+ assertTrue(estimatedFuture.isDone());
}
private void basicSanityChecks(Wallet wallet, Transaction t, Address fromAddress, Address destination) throws ScriptException {