Search in sources :

Example 16 with Wallet

use of org.bitcoinj.wallet.Wallet in project bitcoin-wallet by bitcoin-wallet.

the class EncryptKeysDialogFragment method handleGo.

private void handleGo() {
    final String oldPassword = Strings.emptyToNull(oldPasswordView.getText().toString().trim());
    final String newPassword = Strings.emptyToNull(newPasswordView.getText().toString().trim());
    if (oldPassword != null && newPassword != null)
        log.info("changing spending password");
    else if (newPassword != null)
        log.info("setting spending password");
    else if (oldPassword != null)
        log.info("removing spending password");
    else
        throw new IllegalStateException();
    state = State.CRYPTING;
    updateView();
    backgroundHandler.post(() -> {
        // For the old key, we use the key crypter that was used to derive the password in the first
        // place.
        final KeyCrypter oldKeyCrypter = wallet.getKeyCrypter();
        final KeyParameter oldKey = oldKeyCrypter != null && oldPassword != null ? oldKeyCrypter.deriveKey(oldPassword) : null;
        // For the new key, we create a new key crypter according to the desired parameters.
        final KeyCrypterScrypt keyCrypter = new KeyCrypterScrypt(application.scryptIterationsTarget());
        final KeyParameter newKey = newPassword != null ? keyCrypter.deriveKey(newPassword) : null;
        handler.post(() -> {
            // Decrypt from old password
            if (wallet.isEncrypted()) {
                if (oldKey == null) {
                    log.info("wallet is encrypted, but did not provide spending password");
                    state = State.INPUT;
                    oldPasswordView.requestFocus();
                } else {
                    try {
                        wallet.decrypt(oldKey);
                        state = State.DONE;
                        log.info("wallet successfully decrypted");
                    } catch (final Wallet.BadWalletEncryptionKeyException x) {
                        log.info("wallet decryption failed, bad spending password: " + x.getMessage());
                        badPasswordView.setVisibility(View.VISIBLE);
                        state = State.INPUT;
                        oldPasswordView.requestFocus();
                    }
                }
            }
            // Use opportunity to maybe upgrade wallet
            if (wallet.isDeterministicUpgradeRequired(Constants.UPGRADE_OUTPUT_SCRIPT_TYPE) && !wallet.isEncrypted())
                wallet.upgradeToDeterministic(Constants.UPGRADE_OUTPUT_SCRIPT_TYPE, null);
            // Encrypt to new password
            if (newKey != null && !wallet.isEncrypted()) {
                wallet.encrypt(keyCrypter, newKey);
                config.updateLastEncryptKeysTime();
                log.info("wallet successfully encrypted, using key derived by new spending password ({} scrypt iterations)", keyCrypter.getScryptParameters().getN());
                state = State.DONE;
            }
            updateView();
            if (state == State.DONE) {
                WalletUtils.autoBackupWallet(activity, wallet);
                // trigger load manually because of missing callbacks for encryption state
                activityViewModel.walletEncrypted.load();
                handler.postDelayed(() -> dismiss(), 2000);
            }
        });
    });
}
Also used : KeyCrypter(org.bitcoinj.crypto.KeyCrypter) Wallet(org.bitcoinj.wallet.Wallet) KeyParameter(org.bouncycastle.crypto.params.KeyParameter) KeyCrypterScrypt(org.bitcoinj.crypto.KeyCrypterScrypt)

Example 17 with Wallet

use of org.bitcoinj.wallet.Wallet in project bitcoin-wallet by bitcoin-wallet.

the class BlockchainService method onCreate.

@Override
public void onCreate() {
    serviceUpTime = Stopwatch.createStarted();
    log.debug(".onCreate()");
    super.onCreate();
    application = (WalletApplication) getApplication();
    config = application.getConfiguration();
    pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
    log.info("acquiring {}", wakeLock);
    wakeLock.acquire();
    connectivityNotification.setColor(getColor(R.color.fg_network_significant));
    connectivityNotification.setContentTitle(getString(config.isTrustedPeersOnly() ? R.string.notification_connectivity_syncing_trusted_peer : R.string.notification_connectivity_syncing_message));
    connectivityNotification.setContentIntent(PendingIntent.getActivity(BlockchainService.this, 0, new Intent(BlockchainService.this, WalletActivity.class), 0));
    connectivityNotification.setWhen(System.currentTimeMillis());
    connectivityNotification.setOngoing(true);
    connectivityNotification.setPriority(NotificationCompat.PRIORITY_LOW);
    startForeground(0);
    backgroundThread = new HandlerThread("backgroundThread", Process.THREAD_PRIORITY_BACKGROUND);
    backgroundThread.start();
    backgroundHandler = new Handler(backgroundThread.getLooper());
    addressBookDao = AddressBookDatabase.getDatabase(application).addressBookDao();
    blockChainFile = new File(getDir("blockstore", Context.MODE_PRIVATE), Constants.Files.BLOCKCHAIN_FILENAME);
    config.registerOnSharedPreferenceChangeListener(preferenceChangeListener);
    registerReceiver(deviceIdleModeReceiver, new IntentFilter(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED));
    peerConnectivityListener = new PeerConnectivityListener();
    broadcastPeerState(0);
    final WalletBalanceLiveData walletBalance = new WalletBalanceLiveData(application);
    final SelectedExchangeRateLiveData exchangeRate = new SelectedExchangeRateLiveData(application);
    walletBalance.observe(this, balance -> {
        final ExchangeRateEntry rate = exchangeRate.getValue();
        if (balance != null)
            WalletBalanceWidgetProvider.updateWidgets(BlockchainService.this, balance, rate != null ? rate.exchangeRate() : null);
    });
    exchangeRate.observe(this, rate -> {
        final Coin balance = walletBalance.getValue();
        if (balance != null)
            WalletBalanceWidgetProvider.updateWidgets(BlockchainService.this, balance, rate != null ? rate.exchangeRate() : null);
    });
    wallet = new WalletLiveData(application);
    wallet.observe(this, new Observer<Wallet>() {

        @Override
        public void onChanged(final Wallet wallet) {
            BlockchainService.this.wallet.removeObserver(this);
            final boolean blockChainFileExists = blockChainFile.exists();
            if (!blockChainFileExists) {
                log.info("blockchain does not exist, resetting wallet");
                wallet.reset();
            }
            try {
                blockStore = new SPVBlockStore(Constants.NETWORK_PARAMETERS, blockChainFile, Constants.Files.BLOCKCHAIN_STORE_CAPACITY, true);
                // detect corruptions as early as possible
                blockStore.getChainHead();
                final long earliestKeyCreationTimeSecs = wallet.getEarliestKeyCreationTime();
                if (!blockChainFileExists && earliestKeyCreationTimeSecs > 0) {
                    try {
                        log.info("loading checkpoints for birthdate {} from '{}'", Utils.dateTimeFormat(earliestKeyCreationTimeSecs * 1000), Constants.Files.CHECKPOINTS_ASSET);
                        final Stopwatch watch = Stopwatch.createStarted();
                        final InputStream checkpointsInputStream = getAssets().open(Constants.Files.CHECKPOINTS_ASSET);
                        CheckpointManager.checkpoint(Constants.NETWORK_PARAMETERS, checkpointsInputStream, blockStore, earliestKeyCreationTimeSecs);
                        watch.stop();
                        log.info("checkpoints loaded, took {}", watch);
                    } catch (final IOException x) {
                        log.error("problem reading checkpoints, continuing without", x);
                    }
                }
            } catch (final BlockStoreException x) {
                blockChainFile.delete();
                final String msg = "blockstore cannot be created";
                log.error(msg, x);
                throw new Error(msg, x);
            }
            try {
                blockChain = new BlockChain(Constants.NETWORK_PARAMETERS, wallet, blockStore);
            } catch (final BlockStoreException x) {
                throw new Error("blockchain cannot be created", x);
            }
            observeLiveDatasThatAreDependentOnWalletAndBlockchain();
        }
    });
}
Also used : IntentFilter(android.content.IntentFilter) BlockStoreException(org.bitcoinj.store.BlockStoreException) BlockChain(org.bitcoinj.core.BlockChain) Wallet(org.bitcoinj.wallet.Wallet) InputStream(java.io.InputStream) SPVBlockStore(org.bitcoinj.store.SPVBlockStore) Stopwatch(com.google.common.base.Stopwatch) Handler(android.os.Handler) PendingIntent(android.app.PendingIntent) Intent(android.content.Intent) IOException(java.io.IOException) WalletLiveData(de.schildbach.wallet.data.WalletLiveData) ExchangeRateEntry(de.schildbach.wallet.exchangerate.ExchangeRateEntry) Coin(org.bitcoinj.core.Coin) HandlerThread(android.os.HandlerThread) SelectedExchangeRateLiveData(de.schildbach.wallet.data.SelectedExchangeRateLiveData) File(java.io.File) WalletBalanceLiveData(de.schildbach.wallet.data.WalletBalanceLiveData)

Example 18 with Wallet

use of org.bitcoinj.wallet.Wallet in project bitcoin-wallet by bitcoin-wallet.

the class SendCoinsFragment method signAndSendPayment.

private void signAndSendPayment(final KeyParameter encryptionKey) {
    setState(SendCoinsViewModel.State.SIGNING);
    // final payment intent
    final PaymentIntent finalPaymentIntent = viewModel.paymentIntent.mergeWithEditedValues(amountCalculatorLink.getAmount(), viewModel.validatedAddress != null ? viewModel.validatedAddress.address : null);
    final Coin finalAmount = finalPaymentIntent.getAmount();
    // prepare send request
    final Map<FeeCategory, Coin> fees = viewModel.dynamicFees.getValue();
    final Wallet wallet = walletActivityViewModel.wallet.getValue();
    final SendRequest sendRequest = finalPaymentIntent.toSendRequest();
    sendRequest.emptyWallet = viewModel.paymentIntent.mayEditAmount() && finalAmount.equals(wallet.getBalance(BalanceType.AVAILABLE));
    sendRequest.feePerKb = fees.get(viewModel.feeCategory);
    sendRequest.memo = viewModel.paymentIntent.memo;
    sendRequest.exchangeRate = amountCalculatorLink.getExchangeRate();
    sendRequest.aesKey = encryptionKey;
    final Coin fee = viewModel.dryrunTransaction.getFee();
    if (fee.isGreaterThan(finalAmount)) {
        setState(SendCoinsViewModel.State.INPUT);
        final MonetaryFormat btcFormat = config.getFormat();
        final DialogBuilder dialog = DialogBuilder.warn(activity, R.string.send_coins_fragment_significant_fee_title, R.string.send_coins_fragment_significant_fee_message, btcFormat.format(fee), btcFormat.format(finalAmount));
        dialog.setPositiveButton(R.string.send_coins_fragment_button_send, (d, which) -> sendPayment(sendRequest, finalAmount));
        dialog.setNegativeButton(R.string.button_cancel, null);
        dialog.show();
    } else {
        sendPayment(sendRequest, finalAmount);
    }
}
Also used : Coin(org.bitcoinj.core.Coin) SendRequest(org.bitcoinj.wallet.SendRequest) MonetaryFormat(org.bitcoinj.utils.MonetaryFormat) Wallet(org.bitcoinj.wallet.Wallet) PaymentIntent(de.schildbach.wallet.data.PaymentIntent) DialogBuilder(de.schildbach.wallet.ui.DialogBuilder)

Example 19 with Wallet

use of org.bitcoinj.wallet.Wallet in project bitcoin-wallet by bitcoin-wallet.

the class SendCoinsFragment method updateView.

private void updateView() {
    final Wallet wallet = walletActivityViewModel.wallet.getValue();
    final Map<FeeCategory, Coin> fees = viewModel.dynamicFees.getValue();
    final BlockchainState blockchainState = application.blockchainState.getValue();
    final Map<String, AddressBookEntry> addressBook = AddressBookEntry.asMap(viewModel.addressBook.getValue());
    if (viewModel.paymentIntent != null) {
        final MonetaryFormat btcFormat = config.getFormat();
        getView().setVisibility(View.VISIBLE);
        if (viewModel.paymentIntent.hasPayee()) {
            payeeNameView.setVisibility(View.VISIBLE);
            payeeNameView.setText(viewModel.paymentIntent.payeeName);
            payeeVerifiedByView.setVisibility(View.VISIBLE);
            final String verifiedBy = viewModel.paymentIntent.payeeVerifiedBy != null ? viewModel.paymentIntent.payeeVerifiedBy : getString(R.string.send_coins_fragment_payee_verified_by_unknown);
            payeeVerifiedByView.setText(Constants.CHAR_CHECKMARK + String.format(getString(R.string.send_coins_fragment_payee_verified_by), verifiedBy));
        } else {
            payeeNameView.setVisibility(View.GONE);
            payeeVerifiedByView.setVisibility(View.GONE);
        }
        if (viewModel.paymentIntent.hasOutputs()) {
            payeeGroup.setVisibility(View.VISIBLE);
            receivingAddressView.setVisibility(View.GONE);
            receivingStaticView.setVisibility(!viewModel.paymentIntent.hasPayee() || viewModel.paymentIntent.payeeVerifiedBy == null ? View.VISIBLE : View.GONE);
            receivingStaticLabelView.setText(viewModel.paymentIntent.memo);
            if (viewModel.paymentIntent.hasAddress())
                receivingStaticAddressView.setText(WalletUtils.formatAddress(viewModel.paymentIntent.getAddress(), Constants.ADDRESS_FORMAT_GROUP_SIZE, Constants.ADDRESS_FORMAT_LINE_SIZE));
            else
                receivingStaticAddressView.setText(R.string.send_coins_fragment_receiving_address_complex);
        } else if (viewModel.validatedAddress != null) {
            payeeGroup.setVisibility(View.VISIBLE);
            receivingAddressView.setVisibility(View.GONE);
            receivingStaticView.setVisibility(View.VISIBLE);
            receivingStaticAddressView.setText(WalletUtils.formatAddress(viewModel.validatedAddress.address, Constants.ADDRESS_FORMAT_GROUP_SIZE, Constants.ADDRESS_FORMAT_LINE_SIZE));
            final String addressBookLabel = addressBookDao.resolveLabel(viewModel.validatedAddress.address.toString());
            final String staticLabel;
            if (addressBookLabel != null)
                staticLabel = addressBookLabel;
            else if (viewModel.validatedAddress.label != null)
                staticLabel = viewModel.validatedAddress.label;
            else
                staticLabel = getString(R.string.address_unlabeled);
            receivingStaticLabelView.setText(staticLabel);
            receivingStaticLabelView.setTextColor(activity.getColor(viewModel.validatedAddress.label != null ? R.color.fg_significant : R.color.fg_insignificant));
        } else if (viewModel.paymentIntent.standard == null) {
            payeeGroup.setVisibility(View.VISIBLE);
            receivingStaticView.setVisibility(View.GONE);
            receivingAddressView.setVisibility(View.VISIBLE);
        } else {
            payeeGroup.setVisibility(View.GONE);
        }
        receivingAddressView.setEnabled(viewModel.state == SendCoinsViewModel.State.INPUT);
        amountGroup.setVisibility(viewModel.paymentIntent.hasAmount() || (viewModel.state != null && viewModel.state.compareTo(SendCoinsViewModel.State.INPUT) >= 0) ? View.VISIBLE : View.GONE);
        amountCalculatorLink.setEnabled(viewModel.state == SendCoinsViewModel.State.INPUT && viewModel.paymentIntent.mayEditAmount());
        final boolean directPaymentVisible;
        if (viewModel.paymentIntent.hasPaymentUrl()) {
            if (viewModel.paymentIntent.isBluetoothPaymentUrl())
                directPaymentVisible = bluetoothAdapter != null;
            else
                directPaymentVisible = true;
        } else {
            directPaymentVisible = false;
        }
        directPaymentEnableView.setVisibility(directPaymentVisible ? View.VISIBLE : View.GONE);
        directPaymentEnableView.setEnabled(viewModel.state == SendCoinsViewModel.State.INPUT);
        hintView.setVisibility(View.GONE);
        if (viewModel.state == SendCoinsViewModel.State.INPUT) {
            if (blockchainState != null && blockchainState.replaying) {
                hintView.setTextColor(activity.getColor(R.color.fg_error));
                hintView.setVisibility(View.VISIBLE);
                hintView.setText(R.string.send_coins_fragment_hint_replaying);
            } else if (viewModel.paymentIntent.mayEditAddress() && viewModel.validatedAddress == null && !receivingAddressView.getText().toString().trim().isEmpty()) {
                hintView.setTextColor(activity.getColor(R.color.fg_error));
                hintView.setVisibility(View.VISIBLE);
                hintView.setText(R.string.send_coins_fragment_receiving_address_error);
            } else if (viewModel.dryrunException != null) {
                hintView.setTextColor(activity.getColor(R.color.fg_error));
                hintView.setVisibility(View.VISIBLE);
                if (viewModel.dryrunException instanceof DustySendRequested)
                    hintView.setText(getString(R.string.send_coins_fragment_hint_dusty_send));
                else if (viewModel.dryrunException instanceof InsufficientMoneyException)
                    hintView.setText(getString(R.string.send_coins_fragment_hint_insufficient_money, btcFormat.format(((InsufficientMoneyException) viewModel.dryrunException).missing)));
                else if (viewModel.dryrunException instanceof CouldNotAdjustDownwards)
                    hintView.setText(getString(R.string.send_coins_fragment_hint_empty_wallet_failed));
                else
                    hintView.setText(viewModel.dryrunException.toString());
            } else if (viewModel.dryrunTransaction != null && viewModel.dryrunTransaction.getFee() != null) {
                hintView.setVisibility(View.VISIBLE);
                final int hintResId;
                final int colorResId;
                if (viewModel.feeCategory == FeeCategory.ECONOMIC) {
                    hintResId = R.string.send_coins_fragment_hint_fee_economic;
                    colorResId = R.color.fg_less_significant;
                } else if (viewModel.feeCategory == FeeCategory.PRIORITY) {
                    hintResId = R.string.send_coins_fragment_hint_fee_priority;
                    colorResId = R.color.fg_less_significant;
                } else {
                    hintResId = R.string.send_coins_fragment_hint_fee;
                    colorResId = R.color.fg_insignificant;
                }
                hintView.setTextColor(activity.getColor(colorResId));
                hintView.setText(getString(hintResId, btcFormat.format(viewModel.dryrunTransaction.getFee())));
            } else if (viewModel.paymentIntent.mayEditAddress() && viewModel.validatedAddress != null && wallet != null && wallet.isAddressMine(viewModel.validatedAddress.address)) {
                hintView.setTextColor(activity.getColor(R.color.fg_insignificant));
                hintView.setVisibility(View.VISIBLE);
                hintView.setText(R.string.send_coins_fragment_receiving_address_own);
            }
        }
        final Transaction sentTransaction = viewModel.sentTransaction.getValue();
        if (sentTransaction != null && wallet != null) {
            sentTransactionView.setVisibility(View.VISIBLE);
            sentTransactionViewHolder.fullBind(new TransactionsAdapter.ListItem.TransactionItem(activity, sentTransaction, wallet, addressBook, btcFormat, application.maxConnectedPeers()));
        } else {
            sentTransactionView.setVisibility(View.GONE);
        }
        if (viewModel.directPaymentAck != null) {
            directPaymentMessageView.setVisibility(View.VISIBLE);
            directPaymentMessageView.setText(viewModel.directPaymentAck ? R.string.send_coins_fragment_direct_payment_ack : R.string.send_coins_fragment_direct_payment_nack);
        } else {
            directPaymentMessageView.setVisibility(View.GONE);
        }
        viewCancel.setEnabled(viewModel.state != SendCoinsViewModel.State.REQUEST_PAYMENT_REQUEST && viewModel.state != SendCoinsViewModel.State.DECRYPTING && viewModel.state != SendCoinsViewModel.State.SIGNING);
        viewGo.setEnabled(everythingPlausible() && viewModel.dryrunTransaction != null && wallet != null && fees != null && (blockchainState == null || !blockchainState.replaying));
        if (viewModel.state == null || viewModel.state == SendCoinsViewModel.State.REQUEST_PAYMENT_REQUEST) {
            viewCancel.setText(R.string.button_cancel);
            viewGo.setText(null);
        } else if (viewModel.state == SendCoinsViewModel.State.INPUT) {
            viewCancel.setText(R.string.button_cancel);
            viewGo.setText(R.string.send_coins_fragment_button_send);
        } else if (viewModel.state == SendCoinsViewModel.State.DECRYPTING) {
            viewCancel.setText(R.string.button_cancel);
            viewGo.setText(R.string.send_coins_fragment_state_decrypting);
        } else if (viewModel.state == SendCoinsViewModel.State.SIGNING) {
            viewCancel.setText(R.string.button_cancel);
            viewGo.setText(R.string.send_coins_preparation_msg);
        } else if (viewModel.state == SendCoinsViewModel.State.SENDING) {
            viewCancel.setText(R.string.send_coins_fragment_button_back);
            viewGo.setText(R.string.send_coins_sending_msg);
        } else if (viewModel.state == SendCoinsViewModel.State.SENT) {
            viewCancel.setText(R.string.send_coins_fragment_button_back);
            viewGo.setText(R.string.send_coins_sent_msg);
        } else if (viewModel.state == SendCoinsViewModel.State.FAILED) {
            viewCancel.setText(R.string.send_coins_fragment_button_back);
            viewGo.setText(R.string.send_coins_failed_msg);
        }
        final boolean privateKeyPasswordViewVisible = (viewModel.state == SendCoinsViewModel.State.INPUT || viewModel.state == SendCoinsViewModel.State.DECRYPTING) && wallet != null && wallet.isEncrypted();
        privateKeyPasswordViewGroup.setVisibility(privateKeyPasswordViewVisible ? View.VISIBLE : View.GONE);
        privateKeyPasswordView.setEnabled(viewModel.state == SendCoinsViewModel.State.INPUT);
        // focus linking
        final int activeAmountViewId = amountCalculatorLink.activeTextView().getId();
        receivingAddressView.setNextFocusDownId(activeAmountViewId);
        receivingAddressView.setNextFocusForwardId(activeAmountViewId);
        amountCalculatorLink.setNextFocusId(privateKeyPasswordViewVisible ? R.id.send_coins_private_key_password : R.id.send_coins_go);
        privateKeyPasswordView.setNextFocusUpId(activeAmountViewId);
        privateKeyPasswordView.setNextFocusDownId(R.id.send_coins_go);
        privateKeyPasswordView.setNextFocusForwardId(R.id.send_coins_go);
        viewGo.setNextFocusUpId(privateKeyPasswordViewVisible ? R.id.send_coins_private_key_password : activeAmountViewId);
    } else {
        getView().setVisibility(View.GONE);
    }
}
Also used : DustySendRequested(org.bitcoinj.wallet.Wallet.DustySendRequested) MonetaryFormat(org.bitcoinj.utils.MonetaryFormat) Wallet(org.bitcoinj.wallet.Wallet) AddressBookEntry(de.schildbach.wallet.addressbook.AddressBookEntry) InsufficientMoneyException(org.bitcoinj.core.InsufficientMoneyException) CouldNotAdjustDownwards(org.bitcoinj.wallet.Wallet.CouldNotAdjustDownwards) Coin(org.bitcoinj.core.Coin) BlockchainState(de.schildbach.wallet.service.BlockchainState) Transaction(org.bitcoinj.core.Transaction)

Example 20 with Wallet

use of org.bitcoinj.wallet.Wallet in project bitcoin-wallet by bitcoin-wallet.

the class SweepWalletFragment method requestWalletBalance.

private void requestWalletBalance() {
    viewModel.progress.setValue(getString(R.string.sweep_wallet_fragment_request_wallet_balance_progress));
    final RequestWalletBalanceTask.ResultCallback callback = new RequestWalletBalanceTask.ResultCallback() {

        @Override
        public void onResult(final Set<UTXO> utxos) {
            final Wallet wallet = walletActivityViewModel.wallet.getValue();
            viewModel.progress.setValue(null);
            // Filter UTXOs we've already spent and sort the rest.
            final Set<Transaction> walletTxns = wallet.getTransactions(false);
            final Set<UTXO> sortedUtxos = new TreeSet<>(UTXO_COMPARATOR);
            for (final UTXO utxo : utxos) if (!utxoSpentBy(walletTxns, utxo))
                sortedUtxos.add(utxo);
            // Fake transaction funding the wallet to sweep.
            final Map<Sha256Hash, Transaction> fakeTxns = new HashMap<>();
            for (final UTXO utxo : sortedUtxos) {
                Transaction fakeTx = fakeTxns.get(utxo.getHash());
                if (fakeTx == null) {
                    fakeTx = new FakeTransaction(Constants.NETWORK_PARAMETERS, utxo.getHash(), utxo.getHash());
                    fakeTx.getConfidence().setConfidenceType(ConfidenceType.BUILDING);
                    fakeTxns.put(fakeTx.getTxId(), fakeTx);
                }
                final TransactionOutput fakeOutput = new TransactionOutput(Constants.NETWORK_PARAMETERS, fakeTx, utxo.getValue(), utxo.getScript().getProgram());
                // Fill with output dummies as needed.
                while (fakeTx.getOutputs().size() < utxo.getIndex()) fakeTx.addOutput(new TransactionOutput(Constants.NETWORK_PARAMETERS, fakeTx, Coin.NEGATIVE_SATOSHI, new byte[] {}));
                // Add the actual output we will spend later.
                fakeTx.addOutput(fakeOutput);
            }
            final Wallet walletToSweep = viewModel.walletToSweep.getValue();
            walletToSweep.clearTransactions(0);
            for (final Transaction tx : fakeTxns.values()) walletToSweep.addWalletTransaction(new WalletTransaction(WalletTransaction.Pool.UNSPENT, tx));
            log.info("built wallet to sweep:\n{}", walletToSweep.toString(false, false, null, true, false, null));
            viewModel.walletToSweep.setValue(walletToSweep);
        }

        private boolean utxoSpentBy(final Set<Transaction> transactions, final UTXO utxo) {
            for (final Transaction tx : transactions) {
                for (final TransactionInput input : tx.getInputs()) {
                    final TransactionOutPoint outpoint = input.getOutpoint();
                    if (outpoint.getHash().equals(utxo.getHash()) && outpoint.getIndex() == utxo.getIndex())
                        return true;
                }
            }
            return false;
        }

        @Override
        public void onFail(final int messageResId, final Object... messageArgs) {
            viewModel.progress.setValue(null);
            viewModel.showDialogWithRetryRequestBalance.setValue(DialogEvent.warn(R.string.sweep_wallet_fragment_request_wallet_balance_failed_title, messageResId, messageArgs));
        }
    };
    final Wallet walletToSweep = viewModel.walletToSweep.getValue();
    final ECKey key = walletToSweep.getImportedKeys().iterator().next();
    new RequestWalletBalanceTask(backgroundHandler, callback).requestWalletBalance(activity.getAssets(), key);
}
Also used : Set(java.util.Set) TreeSet(java.util.TreeSet) TransactionOutput(org.bitcoinj.core.TransactionOutput) HashMap(java.util.HashMap) Wallet(org.bitcoinj.wallet.Wallet) Sha256Hash(org.bitcoinj.core.Sha256Hash) ECKey(org.bitcoinj.core.ECKey) TransactionInput(org.bitcoinj.core.TransactionInput) UTXO(org.bitcoinj.core.UTXO) Transaction(org.bitcoinj.core.Transaction) WalletTransaction(org.bitcoinj.wallet.WalletTransaction) TreeSet(java.util.TreeSet) WalletTransaction(org.bitcoinj.wallet.WalletTransaction) TransactionOutPoint(org.bitcoinj.core.TransactionOutPoint)

Aggregations

Wallet (org.bitcoinj.wallet.Wallet)119 Transaction (org.bitcoinj.core.Transaction)34 Test (org.junit.Test)24 Coin (org.bitcoinj.core.Coin)23 SendRequest (org.bitcoinj.wallet.SendRequest)18 IOException (java.io.IOException)17 WalletProtobufSerializer (org.bitcoinj.wallet.WalletProtobufSerializer)17 Address (org.bitcoinj.core.Address)16 BlockTest (org.bitcoinj.core.BlockTest)16 ECKey (org.bitcoinj.core.ECKey)15 WalletTransaction (org.bitcoinj.wallet.WalletTransaction)13 List (java.util.List)12 Set (java.util.Set)12 TransactionOutput (org.bitcoinj.core.TransactionOutput)12 TransactionConfidence (org.bitcoinj.core.TransactionConfidence)11 Preferences (bisq.core.user.Preferences)10 Collectors (java.util.stream.Collectors)10 InsufficientMoneyException (org.bitcoinj.core.InsufficientMoneyException)10 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)9 Inject (javax.inject.Inject)9