Search in sources :

Example 11 with MonetaryFormat

use of org.bitcoinj.utils.MonetaryFormat in project bitcoin-wallet by bitcoin-wallet.

the class BootstrapReceiver method maybeShowInactivityNotification.

@WorkerThread
private void maybeShowInactivityNotification(final WalletApplication application) {
    final Configuration config = application.getConfiguration();
    if (!config.remindBalance() || !config.hasBeenUsed() || config.getLastUsedAgo() <= Constants.LAST_USAGE_THRESHOLD_INACTIVE_MS)
        return;
    final Wallet wallet = application.getWallet();
    final Coin estimatedBalance = wallet.getBalance(Wallet.BalanceType.ESTIMATED_SPENDABLE);
    if (!estimatedBalance.isPositive())
        return;
    log.info("detected balance, showing inactivity notification");
    final Coin availableBalance = wallet.getBalance(Wallet.BalanceType.AVAILABLE_SPENDABLE);
    final boolean canDonate = Constants.DONATION_ADDRESS != null && !availableBalance.isLessThan(Constants.SOME_BALANCE_THRESHOLD);
    final MonetaryFormat btcFormat = config.getFormat();
    final String title = application.getString(R.string.notification_inactivity_title);
    final StringBuilder text = new StringBuilder(application.getString(R.string.notification_inactivity_message, btcFormat.format(estimatedBalance)));
    if (canDonate)
        text.append("\n\n").append(application.getString(R.string.notification_inactivity_message_donate));
    final NotificationCompat.Builder notification = new NotificationCompat.Builder(application, Constants.NOTIFICATION_CHANNEL_ID_IMPORTANT);
    notification.setStyle(new NotificationCompat.BigTextStyle().bigText(text));
    notification.setColor(application.getColor(R.color.fg_network_significant));
    notification.setSmallIcon(R.drawable.stat_notify_received_24dp);
    notification.setContentTitle(title);
    notification.setContentText(text);
    notification.setContentIntent(PendingIntent.getActivity(application, 0, new Intent(application, WalletActivity.class), 0));
    notification.setAutoCancel(true);
    if (!canDonate) {
        final Intent dismissIntent = new Intent(application, BootstrapReceiver.class);
        dismissIntent.setAction(ACTION_DISMISS);
        notification.addAction(new NotificationCompat.Action.Builder(0, application.getString(R.string.notification_inactivity_action_dismiss), PendingIntent.getBroadcast(application, 0, dismissIntent, 0)).build());
    }
    final Intent dismissForeverIntent = new Intent(application, BootstrapReceiver.class);
    dismissForeverIntent.setAction(ACTION_DISMISS_FOREVER);
    notification.addAction(new NotificationCompat.Action.Builder(0, application.getString(R.string.notification_inactivity_action_dismiss_forever), PendingIntent.getBroadcast(application, 0, dismissForeverIntent, 0)).build());
    if (canDonate) {
        final Intent donateIntent = new Intent(application, BootstrapReceiver.class);
        donateIntent.setAction(ACTION_DONATE);
        notification.addAction(new NotificationCompat.Action.Builder(0, application.getString(R.string.wallet_options_donate), PendingIntent.getBroadcast(application, 0, donateIntent, 0)).build());
    }
    final NotificationManager nm = (NotificationManager) application.getSystemService(Context.NOTIFICATION_SERVICE);
    nm.notify(Constants.NOTIFICATION_ID_INACTIVITY, notification.build());
}
Also used : MonetaryFormat(org.bitcoinj.utils.MonetaryFormat) Configuration(de.schildbach.wallet.Configuration) NotificationManager(android.app.NotificationManager) Wallet(org.bitcoinj.wallet.Wallet) Intent(android.content.Intent) PendingIntent(android.app.PendingIntent) Coin(org.bitcoinj.core.Coin) NotificationCompat(androidx.core.app.NotificationCompat) WorkerThread(androidx.annotation.WorkerThread)

Example 12 with MonetaryFormat

use of org.bitcoinj.utils.MonetaryFormat in project bitcoin-wallet by bitcoin-wallet.

the class TransactionsAdapter method buildListItems.

public static List<ListItem> buildListItems(final Context context, final List<Transaction> transactions, final WarningType warning, @Nullable final Wallet wallet, @Nullable final Map<String, AddressBookEntry> addressBook, final MonetaryFormat format, final int maxConnectedPeers) {
    final MonetaryFormat noCodeFormat = format.noCode();
    final List<ListItem> items = new ArrayList<>(transactions.size() + 1);
    if (warning != null)
        items.add(new ListItem.WarningItem(warning));
    for (final Transaction tx : transactions) items.add(new ListItem.TransactionItem(context, tx, wallet, addressBook, noCodeFormat, maxConnectedPeers));
    return items;
}
Also used : MonetaryFormat(org.bitcoinj.utils.MonetaryFormat) Transaction(org.bitcoinj.core.Transaction) TransactionItem(de.schildbach.wallet.ui.TransactionsAdapter.ListItem.TransactionItem) ArrayList(java.util.ArrayList)

Example 13 with MonetaryFormat

use of org.bitcoinj.utils.MonetaryFormat in project bitcoin-wallet by bitcoin-wallet.

the class MaintenanceDialogFragment method onCreateDialog.

@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
    final View view = LayoutInflater.from(activity).inflate(R.layout.maintenance_dialog, null);
    Coin value = Coin.ZERO;
    Coin fee = Coin.ZERO;
    for (final Transaction tx : determineMaintenanceTransactions()) {
        value = value.add(tx.getValueSentFromMe(wallet));
        fee = fee.add(tx.getFee());
    }
    final TextView messageView = view.findViewById(R.id.maintenance_dialog_message);
    final MonetaryFormat format = application.getConfiguration().getFormat();
    messageView.setText(getString(R.string.maintenance_dialog_message, format.format(value), format.format(fee)));
    passwordGroup = view.findViewById(R.id.maintenance_dialog_password_group);
    passwordView = view.findViewById(R.id.maintenance_dialog_password);
    passwordView.setText(null);
    badPasswordView = view.findViewById(R.id.maintenance_dialog_bad_password);
    final DialogBuilder builder = DialogBuilder.custom(activity, R.string.maintenance_dialog_title, view);
    // dummies, just to make buttons show
    builder.setPositiveButton(R.string.maintenance_dialog_button_move, null);
    builder.setNegativeButton(R.string.button_dismiss, null);
    builder.setCancelable(false);
    final AlertDialog dialog = builder.create();
    dialog.setCanceledOnTouchOutside(false);
    dialog.setOnShowListener(d -> {
        positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
        negativeButton = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);
        positiveButton.setTypeface(Typeface.DEFAULT_BOLD);
        positiveButton.setOnClickListener(v -> {
            log.info("user decided to do maintenance");
            handleGo();
        });
        negativeButton.setOnClickListener(v -> {
            log.info("user decided to dismiss");
            dismissAllowingStateLoss();
        });
        passwordView.addTextChangedListener(textWatcher);
        MaintenanceDialogFragment.this.dialog = dialog;
        updateView();
    });
    log.info("showing maintenance dialog");
    return dialog;
}
Also used : AlertDialog(android.app.AlertDialog) Coin(org.bitcoinj.core.Coin) MonetaryFormat(org.bitcoinj.utils.MonetaryFormat) Transaction(org.bitcoinj.core.Transaction) TextView(android.widget.TextView) DialogBuilder(de.schildbach.wallet.ui.DialogBuilder) View(android.view.View) TextView(android.widget.TextView)

Example 14 with MonetaryFormat

use of org.bitcoinj.utils.MonetaryFormat in project bitcoin-wallet by bitcoin-wallet.

the class WalletTransactionsViewModel method maybePostList.

private void maybePostList() {
    AsyncTask.execute(() -> {
        org.bitcoinj.core.Context.propagate(Constants.CONTEXT);
        final Set<Transaction> transactions = WalletTransactionsViewModel.this.transactions.getValue();
        final MonetaryFormat format = configFormat.getValue();
        final Map<String, AddressBookEntry> addressBook = AddressBookEntry.asMap(WalletTransactionsViewModel.this.addressBook.getValue());
        if (transactions != null && format != null && addressBook != null) {
            final List<Transaction> filteredTransactions = new ArrayList<>(transactions.size());
            final Wallet wallet = application.getWallet();
            final Direction direction = WalletTransactionsViewModel.this.direction.getValue();
            for (final Transaction tx : transactions) {
                final boolean sent = tx.getValue(wallet).signum() < 0;
                final boolean isInternal = tx.getPurpose() == Purpose.KEY_ROTATION;
                if ((direction == Direction.RECEIVED && !sent && !isInternal) || direction == null || (direction == Direction.SENT && sent && !isInternal))
                    filteredTransactions.add(tx);
            }
            Collections.sort(filteredTransactions, TRANSACTION_COMPARATOR);
            list.postValue(TransactionsAdapter.buildListItems(application, filteredTransactions, warning.getValue(), wallet, addressBook, format, application.maxConnectedPeers()));
        }
    });
}
Also used : MonetaryFormat(org.bitcoinj.utils.MonetaryFormat) Transaction(org.bitcoinj.core.Transaction) Wallet(org.bitcoinj.wallet.Wallet) ArrayList(java.util.ArrayList) AddressBookEntry(de.schildbach.wallet.addressbook.AddressBookEntry)

Example 15 with MonetaryFormat

use of org.bitcoinj.utils.MonetaryFormat 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

MonetaryFormat (org.bitcoinj.utils.MonetaryFormat)15 Coin (org.bitcoinj.core.Coin)8 Intent (android.content.Intent)7 Transaction (org.bitcoinj.core.Transaction)7 Wallet (org.bitcoinj.wallet.Wallet)7 PendingIntent (android.app.PendingIntent)5 DialogBuilder (de.schildbach.wallet.ui.DialogBuilder)4 View (android.view.View)3 TextView (android.widget.TextView)3 Activity (android.app.Activity)2 Context (android.content.Context)2 PackageManager (android.content.pm.PackageManager)2 Bundle (android.os.Bundle)2 Handler (android.os.Handler)2 HandlerThread (android.os.HandlerThread)2 Process (android.os.Process)2 Spannable (android.text.Spannable)2 ForegroundColorSpan (android.text.style.ForegroundColorSpan)2 LayoutInflater (android.view.LayoutInflater)2 Menu (android.view.Menu)2