Search in sources :

Example 6 with MonetaryFormat

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

the class BlockchainService method notifyCoinsReceived.

private void notifyCoinsReceived(@Nullable final Address address, final Coin amount, final Sha256Hash transactionHash) {
    notificationCount++;
    notificationAccumulatedAmount = notificationAccumulatedAmount.add(amount);
    if (address != null && !notificationAddresses.contains(address))
        notificationAddresses.add(address);
    final MonetaryFormat btcFormat = config.getFormat();
    final String packageFlavor = application.applicationPackageFlavor();
    final String msgSuffix = packageFlavor != null ? " [" + packageFlavor + "]" : "";
    // summary notification
    final NotificationCompat.Builder summaryNotification = new NotificationCompat.Builder(this, Constants.NOTIFICATION_CHANNEL_ID_RECEIVED);
    summaryNotification.setGroup(Constants.NOTIFICATION_GROUP_KEY_RECEIVED);
    summaryNotification.setGroupSummary(true);
    summaryNotification.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN);
    summaryNotification.setWhen(System.currentTimeMillis());
    summaryNotification.setSmallIcon(R.drawable.stat_notify_received_24dp);
    summaryNotification.setContentTitle(getString(R.string.notification_coins_received_msg, btcFormat.format(notificationAccumulatedAmount)) + msgSuffix);
    if (!notificationAddresses.isEmpty()) {
        final StringBuilder text = new StringBuilder();
        for (final Address notificationAddress : notificationAddresses) {
            if (text.length() > 0)
                text.append(", ");
            final String addressStr = notificationAddress.toString();
            final String label = addressBookDao.resolveLabel(addressStr);
            text.append(label != null ? label : addressStr);
        }
        summaryNotification.setContentText(text);
    }
    summaryNotification.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, WalletActivity.class), 0));
    nm.notify(Constants.NOTIFICATION_ID_COINS_RECEIVED, summaryNotification.build());
    // child notification
    final NotificationCompat.Builder childNotification = new NotificationCompat.Builder(this, Constants.NOTIFICATION_CHANNEL_ID_RECEIVED);
    childNotification.setGroup(Constants.NOTIFICATION_GROUP_KEY_RECEIVED);
    childNotification.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN);
    childNotification.setWhen(System.currentTimeMillis());
    childNotification.setColor(getColor(R.color.fg_network_significant));
    childNotification.setSmallIcon(R.drawable.stat_notify_received_24dp);
    final String msg = getString(R.string.notification_coins_received_msg, btcFormat.format(amount)) + msgSuffix;
    childNotification.setTicker(msg);
    childNotification.setContentTitle(msg);
    if (address != null) {
        final String addressStr = address.toString();
        final String addressLabel = addressBookDao.resolveLabel(addressStr);
        if (addressLabel != null)
            childNotification.setContentText(addressLabel);
        else
            childNotification.setContentText(addressStr);
    }
    childNotification.setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, WalletActivity.class), 0));
    childNotification.setSound(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.coins_received));
    nm.notify(transactionHash.toString(), Constants.NOTIFICATION_ID_COINS_RECEIVED, childNotification.build());
}
Also used : MonetaryFormat(org.bitcoinj.utils.MonetaryFormat) InetSocketAddress(java.net.InetSocketAddress) Address(org.bitcoinj.core.Address) PeerAddress(org.bitcoinj.core.PeerAddress) NotificationCompat(androidx.core.app.NotificationCompat) PendingIntent(android.app.PendingIntent) Intent(android.content.Intent)

Example 7 with MonetaryFormat

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

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

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

the class WalletBalanceWidgetProvider method updateWidget.

private static void updateWidget(final Context context, final AppWidgetManager appWidgetManager, final int appWidgetId, final Bundle appWidgetOptions, final Coin balance, @Nullable final ExchangeRate exchangeRate) {
    final WalletApplication application = (WalletApplication) context.getApplicationContext();
    final Configuration config = application.getConfiguration();
    final MonetaryFormat btcFormat = config.getFormat();
    final Spannable balanceStr = new MonetarySpannable(btcFormat.noCode(), balance).applyMarkup(null, MonetarySpannable.STANDARD_INSIGNIFICANT_SPANS);
    final Spannable localBalanceStr;
    if (exchangeRate != null) {
        final Fiat localBalance = exchangeRate.coinToFiat(balance);
        final MonetaryFormat localFormat = Constants.LOCAL_FORMAT.code(0, Constants.PREFIX_ALMOST_EQUAL_TO + GenericUtils.currencySymbol(exchangeRate.fiat.currencyCode));
        final Object[] prefixSpans = new Object[] { MonetarySpannable.SMALLER_SPAN, new ForegroundColorSpan(context.getColor(R.color.fg_insignificant_darkdefault)) };
        localBalanceStr = new MonetarySpannable(localFormat, localBalance).applyMarkup(prefixSpans, MonetarySpannable.STANDARD_INSIGNIFICANT_SPANS);
        if (!Constants.NETWORK_PARAMETERS.getId().equals(NetworkParameters.ID_MAINNET))
            localBalanceStr.setSpan(STRIKE_THRU_SPAN, 0, localBalanceStr.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    } else {
        localBalanceStr = null;
    }
    final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.wallet_balance_widget_content);
    final String currencyCode = btcFormat.code();
    if (MonetaryFormat.CODE_BTC.equals(currencyCode))
        views.setImageViewResource(R.id.widget_wallet_prefix, R.drawable.currency_symbol_btc);
    else if (MonetaryFormat.CODE_MBTC.equals(currencyCode))
        views.setImageViewResource(R.id.widget_wallet_prefix, R.drawable.currency_symbol_mbtc);
    else if (MonetaryFormat.CODE_UBTC.equals(currencyCode))
        views.setImageViewResource(R.id.widget_wallet_prefix, R.drawable.currency_symbol_ubtc);
    views.setTextViewText(R.id.widget_wallet_balance_btc, balanceStr);
    views.setViewVisibility(R.id.widget_wallet_balance_local, localBalanceStr != null ? View.VISIBLE : View.GONE);
    views.setTextViewText(R.id.widget_wallet_balance_local, localBalanceStr);
    if (appWidgetOptions != null) {
        final int minWidth = appWidgetOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
        views.setViewVisibility(R.id.widget_app_icon, minWidth > 400 ? View.VISIBLE : View.GONE);
        views.setViewVisibility(R.id.widget_button_request, minWidth > 300 ? View.VISIBLE : View.GONE);
        views.setViewVisibility(R.id.widget_button_send, minWidth > 300 ? View.VISIBLE : View.GONE);
        views.setViewVisibility(R.id.widget_button_send_qr, minWidth > 200 ? View.VISIBLE : View.GONE);
    }
    views.setOnClickPendingIntent(R.id.widget_button_balance, PendingIntent.getActivity(context, 0, new Intent(context, WalletActivity.class), 0));
    views.setOnClickPendingIntent(R.id.widget_button_request, PendingIntent.getActivity(context, 0, new Intent(context, RequestCoinsActivity.class), 0));
    views.setOnClickPendingIntent(R.id.widget_button_send, PendingIntent.getActivity(context, 0, new Intent(context, SendCoinsActivity.class), 0));
    views.setOnClickPendingIntent(R.id.widget_button_send_qr, PendingIntent.getActivity(context, 0, new Intent(context, SendCoinsQrActivity.class), 0));
    appWidgetManager.updateAppWidget(appWidgetId, views);
}
Also used : MonetaryFormat(org.bitcoinj.utils.MonetaryFormat) ForegroundColorSpan(android.text.style.ForegroundColorSpan) Intent(android.content.Intent) PendingIntent(android.app.PendingIntent) MonetarySpannable(de.schildbach.wallet.util.MonetarySpannable) RemoteViews(android.widget.RemoteViews) Fiat(org.bitcoinj.utils.Fiat) MonetarySpannable(de.schildbach.wallet.util.MonetarySpannable) Spannable(android.text.Spannable)

Example 10 with MonetaryFormat

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

the class Configuration method getFormat.

public MonetaryFormat getFormat() {
    final int shift = getBtcShift();
    final int minPrecision = shift <= 3 ? 2 : 0;
    final int decimalRepetitions = (getBtcPrecision() - minPrecision) / 2;
    return new MonetaryFormat().shift(shift).minDecimals(minPrecision).repeatOptionalDecimals(2, decimalRepetitions);
}
Also used : MonetaryFormat(org.bitcoinj.utils.MonetaryFormat)

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