Search in sources :

Example 1 with Payment

use of org.bitcoin.protocols.payments.Protos.Payment 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)

Aggregations

Activity (android.app.Activity)1 BluetoothAdapter (android.bluetooth.BluetoothAdapter)1 ComponentName (android.content.ComponentName)1 ContentResolver (android.content.ContentResolver)1 Context (android.content.Context)1 DialogInterface (android.content.DialogInterface)1 Intent (android.content.Intent)1 PackageManager (android.content.pm.PackageManager)1 Uri (android.net.Uri)1 NdefMessage (android.nfc.NdefMessage)1 NfcAdapter (android.nfc.NfcAdapter)1 Bundle (android.os.Bundle)1 Handler (android.os.Handler)1 HandlerThread (android.os.HandlerThread)1 Process (android.os.Process)1 Editable (android.text.Editable)1 TextWatcher (android.text.TextWatcher)1 LayoutInflater (android.view.LayoutInflater)1 Menu (android.view.Menu)1 MenuInflater (android.view.MenuInflater)1