Search in sources :

Example 71 with Address

use of org.bitcoinj.core.Address in project bitcoin-wallet by bitcoin-wallet.

the class SendCoinsFragment method validateReceivingAddress.

private void validateReceivingAddress() {
    try {
        final String addressStr = receivingAddressView.getText().toString().trim();
        if (!addressStr.isEmpty()) {
            final Address address = Address.fromString(Constants.NETWORK_PARAMETERS, addressStr);
            final String label = addressBookDao.resolveLabel(address.toString());
            viewModel.validatedAddress = new AddressAndLabel(Constants.NETWORK_PARAMETERS, address.toString(), label);
            receivingAddressView.setText(null);
            log.info("Locked to valid address: {}", viewModel.validatedAddress);
        }
    } catch (final AddressFormatException x) {
    // swallow
    }
}
Also used : AddressFormatException(org.bitcoinj.core.AddressFormatException) Address(org.bitcoinj.core.Address) AddressAndLabel(de.schildbach.wallet.ui.AddressAndLabel)

Example 72 with Address

use of org.bitcoinj.core.Address in project bitcoin-wallet by bitcoin-wallet.

the class SendCoinsFragment method sendPayment.

private void sendPayment(final SendRequest sendRequest, final Coin finalAmount) {
    final Wallet wallet = walletActivityViewModel.wallet.getValue();
    new SendCoinsOfflineTask(wallet, backgroundHandler) {

        @Override
        protected void onSuccess(final Transaction transaction) {
            viewModel.sentTransaction.setValue(transaction);
            setState(SendCoinsViewModel.State.SENDING);
            final Address refundAddress = viewModel.paymentIntent.standard == Standard.BIP70 ? wallet.freshAddress(KeyPurpose.REFUND) : null;
            final Payment payment = PaymentProtocol.createPaymentMessage(Collections.singletonList(transaction), finalAmount, refundAddress, null, viewModel.paymentIntent.payeeData);
            if (directPaymentEnableView.isChecked())
                directPay(payment);
            final ListenableFuture<Transaction> future = walletActivityViewModel.broadcastTransaction(transaction);
            future.addListener(() -> {
                // Auto-close the dialog after a short delay
                if (config.getSendCoinsAutoclose())
                    handler.postDelayed(() -> activity.finish(), Constants.AUTOCLOSE_DELAY_MS);
            }, Threading.THREAD_POOL);
            final ComponentName callingActivity = activity.getCallingActivity();
            if (callingActivity != null) {
                log.info("returning result to calling activity: {}", callingActivity.flattenToString());
                final Intent result = new Intent();
                BitcoinIntegration.transactionHashToResult(result, transaction.getTxId().toString());
                if (viewModel.paymentIntent.standard == Standard.BIP70)
                    BitcoinIntegration.paymentToResult(result, payment.toByteArray());
                activity.setResult(Activity.RESULT_OK, result);
            }
        }

        private void directPay(final Payment payment) {
            final DirectPaymentTask.ResultCallback callback = new DirectPaymentTask.ResultCallback() {

                @Override
                public void onResult(final boolean ack) {
                    viewModel.directPaymentAck = ack;
                    if (viewModel.state == SendCoinsViewModel.State.SENDING)
                        setState(SendCoinsViewModel.State.SENT);
                    updateView();
                }

                @Override
                public void onFail(final int messageResId, final Object... messageArgs) {
                    final DialogBuilder dialog = DialogBuilder.warn(activity, R.string.send_coins_fragment_direct_payment_failed_title, viewModel.paymentIntent.paymentUrl + "\n" + getString(messageResId, messageArgs) + "\n\n" + getString(R.string.send_coins_fragment_direct_payment_failed_msg));
                    dialog.setPositiveButton(R.string.button_retry, (d, which) -> directPay(payment));
                    dialog.setNegativeButton(R.string.button_dismiss, null);
                    dialog.show();
                }
            };
            if (viewModel.paymentIntent.isHttpPaymentUrl()) {
                new DirectPaymentTask.HttpPaymentTask(backgroundHandler, callback, viewModel.paymentIntent.paymentUrl, application.httpUserAgent()).send(payment);
            } else if (viewModel.paymentIntent.isBluetoothPaymentUrl() && bluetoothAdapter != null && bluetoothAdapter.isEnabled()) {
                new DirectPaymentTask.BluetoothPaymentTask(backgroundHandler, callback, bluetoothAdapter, Bluetooth.getBluetoothMac(viewModel.paymentIntent.paymentUrl)).send(payment);
            }
        }

        @Override
        protected void onInsufficientMoney(final Coin missing) {
            setState(SendCoinsViewModel.State.INPUT);
            final Coin estimated = wallet.getBalance(BalanceType.ESTIMATED);
            final Coin available = wallet.getBalance(BalanceType.AVAILABLE);
            final Coin pending = estimated.subtract(available);
            final MonetaryFormat btcFormat = config.getFormat();
            final StringBuilder msg = new StringBuilder();
            msg.append(getString(R.string.send_coins_fragment_insufficient_money_msg1, btcFormat.format(missing)));
            if (pending.signum() > 0)
                msg.append("\n\n").append(getString(R.string.send_coins_fragment_pending, btcFormat.format(pending)));
            if (viewModel.paymentIntent.mayEditAmount())
                msg.append("\n\n").append(getString(R.string.send_coins_fragment_insufficient_money_msg2));
            final DialogBuilder dialog = DialogBuilder.warn(activity, R.string.send_coins_fragment_insufficient_money_title, msg);
            if (viewModel.paymentIntent.mayEditAmount()) {
                dialog.setPositiveButton(R.string.send_coins_options_empty, (d, which) -> handleEmpty());
                dialog.setNegativeButton(R.string.button_cancel, null);
            } else {
                dialog.setNeutralButton(R.string.button_dismiss, null);
            }
            dialog.show();
        }

        @Override
        protected void onInvalidEncryptionKey() {
            setState(SendCoinsViewModel.State.INPUT);
            privateKeyBadPasswordView.setVisibility(View.VISIBLE);
            privateKeyPasswordView.requestFocus();
        }

        @Override
        protected void onEmptyWalletFailed() {
            setState(SendCoinsViewModel.State.INPUT);
            final DialogBuilder dialog = DialogBuilder.warn(activity, R.string.send_coins_fragment_empty_wallet_failed_title, R.string.send_coins_fragment_hint_empty_wallet_failed);
            dialog.setNeutralButton(R.string.button_dismiss, null);
            dialog.show();
        }

        @Override
        protected void onFailure(Exception exception) {
            setState(SendCoinsViewModel.State.FAILED);
            final DialogBuilder dialog = DialogBuilder.warn(activity, R.string.send_coins_error_msg, exception.toString());
            dialog.setNeutralButton(R.string.button_dismiss, null);
            dialog.show();
        }
    }.sendCoinsOffline(// send asynchronously
    sendRequest);
}
Also used : Bundle(android.os.Bundle) Transaction(org.bitcoinj.core.Transaction) PackageManager(android.content.pm.PackageManager) Coin(org.bitcoinj.core.Coin) Uri(android.net.Uri) LoggerFactory(org.slf4j.LoggerFactory) ScanActivity(de.schildbach.wallet.ui.scan.ScanActivity) AbstractWalletActivityViewModel(de.schildbach.wallet.ui.AbstractWalletActivityViewModel) Process(android.os.Process) BlockchainState(de.schildbach.wallet.service.BlockchainState) OnFocusChangeListener(android.view.View.OnFocusChangeListener) CheckBox(android.widget.CheckBox) ContentResolver(android.content.ContentResolver) PrefixedChecksummedBytes(org.bitcoinj.core.PrefixedChecksummedBytes) PaymentProtocol(org.bitcoinj.protocols.payments.PaymentProtocol) SendRequest(org.bitcoinj.wallet.SendRequest) Handler(android.os.Handler) Map(java.util.Map) Fragment(androidx.fragment.app.Fragment) View(android.view.View) Button(android.widget.Button) R(de.schildbach.wallet.R) AdapterView(android.widget.AdapterView) Configuration(de.schildbach.wallet.Configuration) NdefMessage(android.nfc.NdefMessage) Constants(de.schildbach.wallet.Constants) WalletUtils(de.schildbach.wallet.util.WalletUtils) AddressFormatException(org.bitcoinj.core.AddressFormatException) PaymentIntent(de.schildbach.wallet.data.PaymentIntent) BalanceType(org.bitcoinj.wallet.Wallet.BalanceType) BinaryInputParser(de.schildbach.wallet.ui.InputParser.BinaryInputParser) ConfidenceType(org.bitcoinj.core.TransactionConfidence.ConfidenceType) ViewGroup(android.view.ViewGroup) BitcoinIntegration(de.schildbach.wallet.integration.android.BitcoinIntegration) FileNotFoundException(java.io.FileNotFoundException) List(java.util.List) TextView(android.widget.TextView) Nullable(androidx.annotation.Nullable) StreamInputParser(de.schildbach.wallet.ui.InputParser.StreamInputParser) TransactionsAdapter(de.schildbach.wallet.ui.TransactionsAdapter) Address(org.bitcoinj.core.Address) DustySendRequested(org.bitcoinj.wallet.Wallet.DustySendRequested) NfcAdapter(android.nfc.NfcAdapter) AddressAndLabel(de.schildbach.wallet.ui.AddressAndLabel) TextWatcher(android.text.TextWatcher) Joiner(com.google.common.base.Joiner) KeyPurpose(org.bitcoinj.wallet.KeyChain.KeyPurpose) Context(android.content.Context) AddressBookEntry(de.schildbach.wallet.addressbook.AddressBookEntry) CurrencyAmountView(de.schildbach.wallet.ui.CurrencyAmountView) TransactionConfidence(org.bitcoinj.core.TransactionConfidence) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Wallet(org.bitcoinj.wallet.Wallet) Filter(android.widget.Filter) Intent(android.content.Intent) Editable(android.text.Editable) MenuItem(android.view.MenuItem) AnimationUtils(android.view.animation.AnimationUtils) ProgressDialogFragment(de.schildbach.wallet.ui.ProgressDialogFragment) VerificationException(org.bitcoinj.core.VerificationException) Nfc(de.schildbach.wallet.util.Nfc) MenuInflater(android.view.MenuInflater) Menu(android.view.Menu) LinkedList(java.util.LinkedList) KeyParameter(org.bouncycastle.crypto.params.KeyParameter) DialogInterface(android.content.DialogInterface) FragmentManager(androidx.fragment.app.FragmentManager) Logger(org.slf4j.Logger) BluetoothAdapter(android.bluetooth.BluetoothAdapter) ViewModelProvider(androidx.lifecycle.ViewModelProvider) ComponentName(android.content.ComponentName) LayoutInflater(android.view.LayoutInflater) Payment(org.bitcoin.protocols.payments.Protos.Payment) Bluetooth(de.schildbach.wallet.util.Bluetooth) CouldNotAdjustDownwards(org.bitcoinj.wallet.Wallet.CouldNotAdjustDownwards) InsufficientMoneyException(org.bitcoinj.core.InsufficientMoneyException) MonetaryFormat(org.bitcoinj.utils.MonetaryFormat) AutoCompleteTextView(android.widget.AutoCompleteTextView) CurrencyCalculatorLink(de.schildbach.wallet.ui.CurrencyCalculatorLink) Threading(org.bitcoinj.utils.Threading) AddressBookDao(de.schildbach.wallet.addressbook.AddressBookDao) ArrayAdapter(android.widget.ArrayAdapter) AbstractWalletActivity(de.schildbach.wallet.ui.AbstractWalletActivity) DialogBuilder(de.schildbach.wallet.ui.DialogBuilder) HandlerThread(android.os.HandlerThread) StringInputParser(de.schildbach.wallet.ui.InputParser.StringInputParser) WalletApplication(de.schildbach.wallet.WalletApplication) DirectPaymentTask(de.schildbach.wallet.offline.DirectPaymentTask) Activity(android.app.Activity) Collections(java.util.Collections) EditText(android.widget.EditText) AddressBookDatabase(de.schildbach.wallet.addressbook.AddressBookDatabase) Standard(de.schildbach.wallet.data.PaymentIntent.Standard) InputStream(java.io.InputStream) MonetaryFormat(org.bitcoinj.utils.MonetaryFormat) Address(org.bitcoinj.core.Address) Wallet(org.bitcoinj.wallet.Wallet) PaymentIntent(de.schildbach.wallet.data.PaymentIntent) Intent(android.content.Intent) DirectPaymentTask(de.schildbach.wallet.offline.DirectPaymentTask) AddressFormatException(org.bitcoinj.core.AddressFormatException) FileNotFoundException(java.io.FileNotFoundException) VerificationException(org.bitcoinj.core.VerificationException) InsufficientMoneyException(org.bitcoinj.core.InsufficientMoneyException) Coin(org.bitcoinj.core.Coin) Payment(org.bitcoin.protocols.payments.Protos.Payment) Transaction(org.bitcoinj.core.Transaction) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) ComponentName(android.content.ComponentName) DialogBuilder(de.schildbach.wallet.ui.DialogBuilder)

Example 73 with Address

use of org.bitcoinj.core.Address in project bitcoin-wallet by bitcoin-wallet.

the class RequestWalletBalanceTask method requestWalletBalance.

public void requestWalletBalance(final AssetManager assets, final ECKey key) {
    backgroundHandler.post(new Runnable() {

        @Override
        public void run() {
            org.bitcoinj.core.Context.propagate(Constants.CONTEXT);
            final Address legacyAddress = LegacyAddress.fromKey(Constants.NETWORK_PARAMETERS, key);
            final Script[] outputScripts;
            final String addressesStr;
            if (key.isCompressed()) {
                final Address segwitAddress = SegwitAddress.fromKey(Constants.NETWORK_PARAMETERS, key);
                outputScripts = new Script[] { ScriptBuilder.createP2PKHOutputScript(legacyAddress.getHash()), ScriptBuilder.createP2WPKHOutputScript(segwitAddress.getHash()) };
                addressesStr = legacyAddress.toString() + "," + segwitAddress.toString();
            } else {
                outputScripts = new Script[] { ScriptBuilder.createP2PKHOutputScript(legacyAddress.getHash()) };
                addressesStr = legacyAddress.toString();
            }
            final List<ElectrumServer> servers = loadElectrumServers(Assets.open(assets, Constants.Files.ELECTRUM_SERVERS_ASSET));
            final List<Callable<Set<UTXO>>> tasks = new ArrayList<>(servers.size());
            for (final ElectrumServer server : servers) {
                tasks.add(() -> {
                    log.info("{} - trying to request wallet balance for {}", server.socketAddress, addressesStr);
                    try (final Socket socket = connect(server)) {
                        final BufferedSink sink = Okio.buffer(Okio.sink(socket));
                        sink.timeout().timeout(5000, TimeUnit.MILLISECONDS);
                        final BufferedSource source = Okio.buffer(Okio.source(socket));
                        source.timeout().timeout(5000, TimeUnit.MILLISECONDS);
                        final Moshi moshi = new Moshi.Builder().build();
                        final JsonAdapter<ElectrumRequest> requestAdapter = moshi.adapter(ElectrumRequest.class);
                        final JsonAdapter<ListunspentResponse> listunspentResponseAdapter = moshi.adapter(ListunspentResponse.class);
                        final JsonAdapter<TransactionResponse> transactionResponseAdapter = moshi.adapter(TransactionResponse.class);
                        final Set<UTXO> utxos = new HashSet<>();
                        for (final Script outputScript : outputScripts) {
                            requestAdapter.toJson(sink, new ElectrumRequest(outputScript.getScriptType().ordinal(), "blockchain.scripthash.listunspent", new String[] { Constants.HEX.encode(Sha256Hash.of(outputScript.getProgram()).getReversedBytes()) }));
                            sink.writeUtf8("\n").flush();
                            final ListunspentResponse listunspentResponse = listunspentResponseAdapter.fromJson(source);
                            final int expectedResponseId = outputScript.getScriptType().ordinal();
                            if (listunspentResponse.id != expectedResponseId) {
                                log.warn("{} - id mismatch listunspentResponse:{} vs request:{}", server.socketAddress, listunspentResponse.id, expectedResponseId);
                                return null;
                            }
                            if (listunspentResponse.error != null) {
                                log.info("{} - server error {}: {}", server.socketAddress, listunspentResponse.error.code, listunspentResponse.error.message);
                                return null;
                            }
                            if (listunspentResponse.result == null) {
                                log.info("{} - missing result", server.socketAddress);
                                return null;
                            }
                            for (final ListunspentResponse.Utxo responseUtxo : listunspentResponse.result) {
                                final Sha256Hash utxoHash = Sha256Hash.wrap(responseUtxo.tx_hash);
                                final int utxoIndex = responseUtxo.tx_pos;
                                // the value cannot be trusted; will be validated below
                                final Coin utxoValue = Coin.valueOf(responseUtxo.value);
                                final UTXO utxo = new UTXO(utxoHash, utxoIndex, utxoValue, responseUtxo.height, false, outputScript);
                                // validation of value and some sanity checks
                                requestAdapter.toJson(sink, new ElectrumRequest("blockchain.transaction.get", new String[] { Constants.HEX.encode(utxo.getHash().getBytes()) }));
                                sink.writeUtf8("\n").flush();
                                final TransactionResponse transactionResponse = transactionResponseAdapter.fromJson(source);
                                if (transactionResponse.error != null) {
                                    log.info("{} - server error {}: {}", server.socketAddress, transactionResponse.error.code, transactionResponse.error.message);
                                    return null;
                                }
                                if (transactionResponse.result == null) {
                                    log.info("{} - missing result", server.socketAddress);
                                    return null;
                                }
                                final Transaction tx = new Transaction(Constants.NETWORK_PARAMETERS, Constants.HEX.decode(transactionResponse.result));
                                if (!tx.getTxId().equals(utxo.getHash()))
                                    log.warn("{} - lied about txid", server.socketAddress);
                                else if (!tx.getOutput(utxo.getIndex()).getValue().equals(utxo.getValue()))
                                    log.warn("{} - lied about amount", server.socketAddress);
                                else if (!tx.getOutput(utxo.getIndex()).getScriptPubKey().equals(outputScript))
                                    log.warn("{} - lied about output script", server.socketAddress);
                                else
                                    // use valid UTXO
                                    utxos.add(utxo);
                            }
                        }
                        log.info("{} - got {} UTXOs {}", server.socketAddress, utxos.size(), utxos);
                        return utxos;
                    } catch (final ConnectException | SSLPeerUnverifiedException | JsonDataException x) {
                        log.warn("{} - {}", server.socketAddress, x.getMessage());
                        return null;
                    } catch (final IOException x) {
                        log.info(server.socketAddress.toString(), x);
                        return null;
                    } catch (final RuntimeException x) {
                        log.error(server.socketAddress.toString(), x);
                        throw x;
                    }
                });
            }
            final ExecutorService threadPool = Executors.newFixedThreadPool(servers.size(), new ContextPropagatingThreadFactory("request"));
            final List<Future<Set<UTXO>>> futures;
            try {
                futures = threadPool.invokeAll(tasks, 10, TimeUnit.SECONDS);
            } catch (final InterruptedException x) {
                throw new RuntimeException(x);
            } finally {
                threadPool.shutdown();
            }
            final Multiset<UTXO> countedUtxos = HashMultiset.create();
            int numSuccess = 0, numFail = 0, numTimeOuts = 0;
            for (Future<Set<UTXO>> future : futures) {
                if (!future.isCancelled()) {
                    try {
                        final Set<UTXO> utxos = future.get();
                        if (utxos != null) {
                            countedUtxos.addAll(utxos);
                            numSuccess++;
                        } else {
                            numFail++;
                        }
                    } catch (InterruptedException | ExecutionException x) {
                        throw new RuntimeException(x);
                    }
                } else {
                    numTimeOuts++;
                }
            }
            final int trustThreshold = servers.size() / 2;
            for (final Iterator<Multiset.Entry<UTXO>> i = countedUtxos.entrySet().iterator(); i.hasNext(); ) {
                final Multiset.Entry<UTXO> entry = i.next();
                if (entry.getCount() < trustThreshold)
                    i.remove();
            }
            final Set<UTXO> utxos = countedUtxos.elementSet();
            log.info("{} successes, {} fails, {} time-outs, {} UTXOs {}", numSuccess, numFail, numTimeOuts, utxos.size(), utxos);
            if (numSuccess < trustThreshold)
                onFail(R.string.sweep_wallet_fragment_request_wallet_balance_failed_connection);
            else if (utxos.isEmpty())
                onFail(R.string.sweep_wallet_fragment_request_wallet_balance_empty);
            else
                onResult(utxos);
        }

        private Socket connect(final ElectrumServer server) throws IOException {
            final Socket socket;
            if (server.type == ElectrumServer.Type.TLS) {
                final SocketFactory sf = sslTrustAllCertificates();
                socket = sf.createSocket(server.socketAddress.getHostName(), server.socketAddress.getPort());
                final SSLSession sslSession = ((SSLSocket) socket).getSession();
                final Certificate certificate = sslSession.getPeerCertificates()[0];
                final String certificateFingerprint = sslCertificateFingerprint(certificate);
                if (server.certificateFingerprint == null) {
                    // signed by CA
                    if (!HttpsURLConnection.getDefaultHostnameVerifier().verify(server.socketAddress.getHostName(), sslSession))
                        throw new SSLPeerUnverifiedException("Expected " + server.socketAddress.getHostName() + ", got " + sslSession.getPeerPrincipal());
                } else {
                    // self-signed
                    if (!certificateFingerprint.equals(server.certificateFingerprint))
                        throw new SSLPeerUnverifiedException("Expected " + server.certificateFingerprint + " for " + server.socketAddress.getHostName() + ", got " + certificateFingerprint);
                }
            } else if (server.type == ElectrumServer.Type.TCP) {
                socket = new Socket();
                socket.connect(server.socketAddress, 5000);
            } else {
                throw new IllegalStateException("Cannot handle: " + server.type);
            }
            return socket;
        }
    });
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) Moshi(com.squareup.moshi.Moshi) LegacyAddress(org.bitcoinj.core.LegacyAddress) InetSocketAddress(java.net.InetSocketAddress) Address(org.bitcoinj.core.Address) SegwitAddress(org.bitcoinj.core.SegwitAddress) ScriptBuilder(org.bitcoinj.script.ScriptBuilder) Sha256Hash(org.bitcoinj.core.Sha256Hash) BufferedSink(okio.BufferedSink) JsonAdapter(com.squareup.moshi.JsonAdapter) ContextPropagatingThreadFactory(org.bitcoinj.utils.ContextPropagatingThreadFactory) Coin(org.bitcoinj.core.Coin) Iterator(java.util.Iterator) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) BufferedSource(okio.BufferedSource) Script(org.bitcoinj.script.Script) SSLSocketFactory(javax.net.ssl.SSLSocketFactory) SocketFactory(javax.net.SocketFactory) SSLPeerUnverifiedException(javax.net.ssl.SSLPeerUnverifiedException) SSLSession(javax.net.ssl.SSLSession) IOException(java.io.IOException) UTXO(org.bitcoinj.core.UTXO) Transaction(org.bitcoinj.core.Transaction) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) HashMultiset(com.google.common.collect.HashMultiset) Multiset(com.google.common.collect.Multiset) SSLSocket(javax.net.ssl.SSLSocket) Socket(java.net.Socket) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate)

Example 74 with Address

use of org.bitcoinj.core.Address in project bitcoin-wallet by bitcoin-wallet.

the class WalletTransactionsFragment method onClickTransactionContextMenuItem.

@Override
public boolean onClickTransactionContextMenuItem(final MenuItem item, final Sha256Hash transactionId) {
    final Wallet wallet = viewModel.wallet.getValue();
    final Transaction tx = wallet.getTransaction(transactionId);
    final int itemId = item.getItemId();
    if (itemId == R.id.wallet_transactions_context_edit_address) {
        final boolean txSent = tx.getValue(wallet).signum() < 0;
        final Address txAddress = txSent ? WalletUtils.getToAddressOfSent(tx, wallet) : WalletUtils.getWalletAddressOfReceived(tx, wallet);
        viewModel.showEditAddressBookEntryDialog.setValue(new Event<>(txAddress));
        return true;
    } else if (itemId == R.id.wallet_transactions_context_show_qr) {
        final byte[] txSerialized = tx.unsafeBitcoinSerialize();
        final Bitmap qrCodeBitmap = Qr.bitmap(Qr.encodeCompressBinary(txSerialized));
        viewModel.showBitmapDialog.setValue(new Event<>(qrCodeBitmap));
        return true;
    } else if (itemId == R.id.wallet_transactions_context_raise_fee) {
        RaiseFeeDialogFragment.show(fragmentManager, transactionId);
        return true;
    } else if (itemId == R.id.wallet_transactions_context_report_issue) {
        viewModel.showReportIssueDialog.setValue(new Event<>(transactionId));
        return true;
    } else if (itemId == R.id.wallet_transactions_context_browse) {
        final Uri blockExplorerUri = config.getBlockExplorer();
        log.info("Viewing transaction {} on {}", transactionId, blockExplorerUri);
        activity.startExternalDocument(Uri.withAppendedPath(blockExplorerUri, "tx/" + transactionId.toString()));
        return true;
    } else {
        return false;
    }
}
Also used : Bitmap(android.graphics.Bitmap) Transaction(org.bitcoinj.core.Transaction) Address(org.bitcoinj.core.Address) Wallet(org.bitcoinj.wallet.Wallet) Uri(android.net.Uri)

Example 75 with Address

use of org.bitcoinj.core.Address in project bitcoin-wallet by bitcoin-wallet.

the class WalletTransactionsFragment method onCreate.

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.fragmentManager = getChildFragmentManager();
    setHasOptionsMenu(true);
    activityViewModel = new ViewModelProvider(activity).get(WalletActivityViewModel.class);
    viewModel = new ViewModelProvider(this).get(WalletTransactionsViewModel.class);
    viewModel.direction.observe(this, direction -> activity.invalidateOptionsMenu());
    viewModel.transactions.observe(this, transactions -> {
        if (transactions.isEmpty()) {
            viewGroup.setDisplayedChild(0);
            final WalletTransactionsViewModel.Direction direction = viewModel.direction.getValue();
            final WarningType warning = viewModel.warning.getValue();
            final SpannableStringBuilder emptyText = new SpannableStringBuilder(getString(direction == WalletTransactionsViewModel.Direction.SENT ? R.string.wallet_transactions_fragment_empty_text_sent : R.string.wallet_transactions_fragment_empty_text_received));
            emptyText.setSpan(new StyleSpan(Typeface.BOLD), 0, emptyText.length(), SpannableStringBuilder.SPAN_POINT_MARK);
            if (direction != WalletTransactionsViewModel.Direction.SENT)
                emptyText.append("\n\n").append(getString(R.string.wallet_transactions_fragment_empty_text_howto));
            if (warning == WarningType.BACKUP) {
                final int start = emptyText.length();
                emptyText.append("\n\n").append(getString(R.string.wallet_transactions_fragment_empty_remind_backup));
                emptyText.setSpan(new StyleSpan(Typeface.BOLD), start, emptyText.length(), SpannableStringBuilder.SPAN_POINT_MARK);
            }
            emptyView.setText(emptyText);
        } else {
            viewGroup.setDisplayedChild(1);
        }
    });
    viewModel.selectedTransaction.observe(this, transactionId -> {
        adapter.setSelectedTransaction(transactionId);
        final int position = adapter.positionOf(transactionId);
        if (position != RecyclerView.NO_POSITION)
            recyclerView.smoothScrollToPosition(position);
    });
    viewModel.list.observe(this, listItems -> {
        adapter.submitList(listItems);
        activityViewModel.transactionsLoadingFinished();
    });
    viewModel.showBitmapDialog.observe(this, new Event.Observer<Bitmap>() {

        @Override
        protected void onEvent(final Bitmap bitmap) {
            BitmapFragment.show(fragmentManager, bitmap);
        }
    });
    viewModel.showEditAddressBookEntryDialog.observe(this, new Event.Observer<Address>() {

        @Override
        protected void onEvent(final Address address) {
            EditAddressBookEntryFragment.edit(fragmentManager, address);
        }
    });
    viewModel.showReportIssueDialog.observe(this, new Event.Observer<Sha256Hash>() {

        @Override
        protected void onEvent(final Sha256Hash transactionHash) {
            ReportIssueDialogFragment.show(fragmentManager, R.string.report_issue_dialog_title_transaction, R.string.report_issue_dialog_message_issue, Constants.REPORT_SUBJECT_ISSUE, transactionHash);
        }
    });
    adapter = new TransactionsAdapter(activity, this, this);
}
Also used : Address(org.bitcoinj.core.Address) Sha256Hash(org.bitcoinj.core.Sha256Hash) WarningType(de.schildbach.wallet.ui.TransactionsAdapter.WarningType) Bitmap(android.graphics.Bitmap) StyleSpan(android.text.style.StyleSpan) SpannableStringBuilder(android.text.SpannableStringBuilder) ViewModelProvider(androidx.lifecycle.ViewModelProvider)

Aggregations

Address (org.bitcoinj.core.Address)78 Transaction (org.bitcoinj.core.Transaction)32 Coin (org.bitcoinj.core.Coin)28 TransactionOutput (org.bitcoinj.core.TransactionOutput)15 TransactionInput (org.bitcoinj.core.TransactionInput)13 ArrayList (java.util.ArrayList)12 AddressEntry (bisq.core.btc.AddressEntry)11 Wallet (org.bitcoinj.wallet.Wallet)11 BtcWalletService (bisq.core.btc.wallet.BtcWalletService)10 AddressFormatException (org.bitcoinj.core.AddressFormatException)10 TransactionConfidence (org.bitcoinj.core.TransactionConfidence)10 IOException (java.io.IOException)9 SendRequest (org.bitcoinj.wallet.SendRequest)9 WalletService (io.bitsquare.btc.WalletService)8 List (java.util.List)8 Collectors (java.util.stream.Collectors)8 Nullable (javax.annotation.Nullable)8 TransactionOutPoint (org.bitcoinj.core.TransactionOutPoint)8 Script (org.bitcoinj.script.Script)8 Intent (android.content.Intent)7