Search in sources :

Example 1 with AddressBookEntry

use of de.schildbach.wallet.addressbook.AddressBookEntry in project bitcoin-wallet by bitcoin-wallet.

the class BlockListAdapter method buildTransactionItems.

private static List<ListItem.TxItem> buildTransactionItems(final Context context, final Sha256Hash blockHash, @Nullable final Set<Transaction> transactions, @Nullable final Wallet wallet, @Nullable final Map<String, AddressBookEntry> addressBook) {
    final List<ListItem.TxItem> transactionItems = new LinkedList<>();
    if (transactions != null && wallet != null) {
        for (final Transaction tx : transactions) {
            final Map<Sha256Hash, Integer> appearsInHashes = tx.getAppearsInHashes();
            if (appearsInHashes != null && appearsInHashes.containsKey(blockHash)) {
                final boolean isCoinBase = tx.isCoinBase();
                final boolean isInternal = tx.getPurpose() == Purpose.KEY_ROTATION;
                final Coin value = tx.getValue(wallet);
                final boolean sent = value.signum() < 0;
                final boolean self = WalletUtils.isEntirelySelf(tx, wallet);
                final Address address;
                if (sent)
                    address = WalletUtils.getToAddressOfSent(tx, wallet);
                else
                    address = WalletUtils.getWalletAddressOfReceived(tx, wallet);
                final CharSequence fromTo;
                if (isInternal || self)
                    fromTo = context.getString(R.string.symbol_internal);
                else if (sent)
                    fromTo = context.getString(R.string.symbol_to);
                else
                    fromTo = context.getString(R.string.symbol_from);
                final CharSequence label;
                if (isCoinBase) {
                    label = context.getString(R.string.wallet_transactions_fragment_coinbase);
                } else if (isInternal || self) {
                    label = context.getString(R.string.wallet_transactions_fragment_internal);
                } else if (address != null && addressBook != null) {
                    final AddressBookEntry entry = addressBook.get(address.toString());
                    if (entry != null)
                        label = entry.getLabel();
                    else
                        label = "?";
                } else {
                    label = "?";
                }
                final CharSequence addressText = label != null ? label : address.toString();
                final Typeface addressTypeface = label != null ? Typeface.DEFAULT : Typeface.MONOSPACE;
                transactionItems.add(new ListItem.TxItem(fromTo, addressText, addressTypeface, label, value));
            }
        }
    }
    return transactionItems;
}
Also used : Address(org.bitcoinj.core.Address) Typeface(android.graphics.Typeface) Sha256Hash(org.bitcoinj.core.Sha256Hash) AddressBookEntry(de.schildbach.wallet.addressbook.AddressBookEntry) LinkedList(java.util.LinkedList) Coin(org.bitcoinj.core.Coin) Transaction(org.bitcoinj.core.Transaction)

Example 2 with AddressBookEntry

use of de.schildbach.wallet.addressbook.AddressBookEntry in project bitcoin-wallet by bitcoin-wallet.

the class AddressBookAdapter method buildListItems.

public static List<ListItem> buildListItems(final Context context, final List<AddressBookEntry> addressBook) {
    final int colorSignificant = context.getColor(R.color.fg_significant);
    final int colorLessSignificant = context.getColor(R.color.fg_less_significant);
    final List<ListItem> items = new ArrayList<>(addressBook.size());
    for (final AddressBookEntry entry : addressBook) {
        final Address address = Address.fromString(Constants.NETWORK_PARAMETERS, entry.getAddress());
        items.add(new ListItem.AddressItem(address, colorSignificant, entry.getLabel(), colorLessSignificant, null, 0));
    }
    return items;
}
Also used : Address(org.bitcoinj.core.Address) ArrayList(java.util.ArrayList) AddressBookEntry(de.schildbach.wallet.addressbook.AddressBookEntry)

Example 3 with AddressBookEntry

use of de.schildbach.wallet.addressbook.AddressBookEntry in project bitcoin-wallet by bitcoin-wallet.

the class AddressBookAdapter method addListItems.

private static void addListItems(final List<ListItem> items, final Collection<Address> addresses, final Context context, @Nullable final Wallet wallet, @Nullable final Map<String, AddressBookEntry> addressBook) {
    final int colorSignificant = context.getColor(R.color.fg_significant);
    final int colorInsignificant = context.getColor(R.color.fg_insignificant);
    final int colorLessSignificant = context.getColor(R.color.fg_less_significant);
    final int colorError = context.getColor(R.color.fg_error);
    final Address currentAddress = wallet != null ? wallet.currentReceiveAddress() : null;
    for (final Address address : addresses) {
        final boolean isRotateKey;
        if (wallet != null) {
            final ECKey key = wallet.findKeyFromAddress(address);
            isRotateKey = wallet.isKeyRotating(key);
        } else {
            isRotateKey = false;
        }
        final int addressColor = isRotateKey ? colorInsignificant : colorSignificant;
        final String label;
        final int labelColor;
        final AddressBookEntry entry = addressBook != null ? addressBook.get(address.toString()) : null;
        if (entry != null) {
            label = entry.getLabel();
            labelColor = isRotateKey ? colorInsignificant : colorLessSignificant;
        } else {
            label = null;
            labelColor = colorInsignificant;
        }
        final String message;
        final int messageColor;
        if (address.equals(currentAddress)) {
            message = context.getString(R.string.address_book_row_current_address);
            messageColor = colorInsignificant;
        } else if (isRotateKey) {
            message = context.getString(R.string.address_book_row_message_compromised_key);
            messageColor = colorError;
        } else {
            message = null;
            messageColor = 0;
        }
        items.add(new ListItem.AddressItem(address, addressColor, label, labelColor, message, messageColor));
    }
}
Also used : Address(org.bitcoinj.core.Address) AddressBookEntry(de.schildbach.wallet.addressbook.AddressBookEntry) ECKey(org.bitcoinj.core.ECKey)

Example 4 with AddressBookEntry

use of de.schildbach.wallet.addressbook.AddressBookEntry 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 5 with AddressBookEntry

use of de.schildbach.wallet.addressbook.AddressBookEntry in project bitcoin-wallet by bitcoin-wallet.

the class EditAddressBookEntryFragment method onCreateDialog.

@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
    final Bundle args = getArguments();
    final Address address = Address.fromString(Constants.NETWORK_PARAMETERS, args.getString(KEY_ADDRESS));
    final String suggestedAddressLabel = args.getString(KEY_SUGGESTED_ADDRESS_LABEL);
    final LayoutInflater inflater = LayoutInflater.from(activity);
    final String label = addressBookDao.resolveLabel(address.toString());
    final boolean isAdd = label == null;
    final boolean isOwn = wallet.isAddressMine(address);
    final int titleResId;
    if (isOwn)
        titleResId = isAdd ? R.string.edit_address_book_entry_dialog_title_add_receive : R.string.edit_address_book_entry_dialog_title_edit_receive;
    else
        titleResId = isAdd ? R.string.edit_address_book_entry_dialog_title_add : R.string.edit_address_book_entry_dialog_title_edit;
    final View view = inflater.inflate(R.layout.edit_address_book_entry_dialog, null);
    final TextView viewAddress = view.findViewById(R.id.edit_address_book_entry_address);
    viewAddress.setText(WalletUtils.formatAddress(address, Constants.ADDRESS_FORMAT_GROUP_SIZE, Constants.ADDRESS_FORMAT_LINE_SIZE));
    final TextView viewLabel = view.findViewById(R.id.edit_address_book_entry_label);
    viewLabel.setText(label != null ? label : suggestedAddressLabel);
    final DialogBuilder dialog = DialogBuilder.custom(activity, titleResId, view);
    final DialogInterface.OnClickListener onClickListener = (d, which) -> {
        if (which == DialogInterface.BUTTON_POSITIVE) {
            final String newLabel = viewLabel.getText().toString().trim();
            if (!newLabel.isEmpty()) {
                addressBookDao.insertOrUpdate(new AddressBookEntry(address.toString(), newLabel));
                maybeSelectAddress(address);
            } else if (!isAdd) {
                addressBookDao.delete(address.toString());
            }
        } else if (which == DialogInterface.BUTTON_NEUTRAL) {
            addressBookDao.delete(address.toString());
        }
        dismiss();
    };
    dialog.setPositiveButton(isAdd ? R.string.button_add : R.string.edit_address_book_entry_dialog_button_edit, onClickListener);
    if (!isAdd)
        dialog.setNeutralButton(R.string.button_delete, onClickListener);
    dialog.setNegativeButton(R.string.button_cancel, (d, which) -> dismissAllowingStateLoss());
    return dialog.create();
}
Also used : Context(android.content.Context) WalletUtils(de.schildbach.wallet.util.WalletUtils) FragmentManager(androidx.fragment.app.FragmentManager) AddressBookEntry(de.schildbach.wallet.addressbook.AddressBookEntry) Bundle(android.os.Bundle) Logger(org.slf4j.Logger) ViewModelProvider(androidx.lifecycle.ViewModelProvider) LayoutInflater(android.view.LayoutInflater) Wallet(org.bitcoinj.wallet.Wallet) LoggerFactory(org.slf4j.LoggerFactory) Dialog(android.app.Dialog) AddressBookDao(de.schildbach.wallet.addressbook.AddressBookDao) TextView(android.widget.TextView) Nullable(androidx.annotation.Nullable) Handler(android.os.Handler) View(android.view.View) R(de.schildbach.wallet.R) Address(org.bitcoinj.core.Address) WalletApplication(de.schildbach.wallet.WalletApplication) Constants(de.schildbach.wallet.Constants) DialogInterface(android.content.DialogInterface) DialogFragment(androidx.fragment.app.DialogFragment) AddressBookDatabase(de.schildbach.wallet.addressbook.AddressBookDatabase) Address(org.bitcoinj.core.Address) DialogInterface(android.content.DialogInterface) Bundle(android.os.Bundle) AddressBookEntry(de.schildbach.wallet.addressbook.AddressBookEntry) TextView(android.widget.TextView) View(android.view.View) LayoutInflater(android.view.LayoutInflater) TextView(android.widget.TextView)

Aggregations

AddressBookEntry (de.schildbach.wallet.addressbook.AddressBookEntry)7 Address (org.bitcoinj.core.Address)4 Wallet (org.bitcoinj.wallet.Wallet)4 Transaction (org.bitcoinj.core.Transaction)3 ArrayList (java.util.ArrayList)2 Coin (org.bitcoinj.core.Coin)2 MonetaryFormat (org.bitcoinj.utils.MonetaryFormat)2 Dialog (android.app.Dialog)1 Context (android.content.Context)1 DialogInterface (android.content.DialogInterface)1 Typeface (android.graphics.Typeface)1 Bundle (android.os.Bundle)1 Handler (android.os.Handler)1 LayoutInflater (android.view.LayoutInflater)1 View (android.view.View)1 TextView (android.widget.TextView)1 Nullable (androidx.annotation.Nullable)1 DialogFragment (androidx.fragment.app.DialogFragment)1 FragmentManager (androidx.fragment.app.FragmentManager)1 ViewModelProvider (androidx.lifecycle.ViewModelProvider)1