Search in sources :

Example 16 with Payment

use of org.thoughtcrime.securesms.payments.Payment in project Signal-Android by signalapp.

the class LedgerReconcileTest method payment.

private static Payment payment(String note, Money.MobileCoin valueAndDirection, Set<ByteString> keyImages, Set<ByteString> publicKeys) {
    UUID uuid = UUID.randomUUID();
    PaymentMetaData.MobileCoinTxoIdentification.Builder builderForValue = PaymentMetaData.MobileCoinTxoIdentification.newBuilder();
    builderForValue.addAllKeyImages(keyImages);
    builderForValue.addAllPublicKey(publicKeys);
    PaymentMetaData paymentMetaData = PaymentMetaData.newBuilder().setMobileCoinTxoIdentification(builderForValue).build();
    return new Payment() {

        @Override
        @NonNull
        public UUID getUuid() {
            return uuid;
        }

        @Override
        @NonNull
        public Payee getPayee() {
            return new Payee(RecipientId.from(1));
        }

        @Override
        public long getBlockIndex() {
            return 0;
        }

        @Override
        public long getBlockTimestamp() {
            return 0;
        }

        @Override
        public long getTimestamp() {
            return 0;
        }

        @Override
        @NonNull
        public Direction getDirection() {
            return valueAndDirection.isNegative() ? Direction.SENT : Direction.RECEIVED;
        }

        @Override
        @NonNull
        public State getState() {
            return State.SUCCESSFUL;
        }

        @Override
        @Nullable
        public FailureReason getFailureReason() {
            return null;
        }

        @Override
        @NonNull
        public String getNote() {
            return note;
        }

        @Override
        @NonNull
        public Money getAmount() {
            return valueAndDirection.abs();
        }

        @Override
        @NonNull
        public Money getFee() {
            return getAmount().toZero();
        }

        @Override
        @NonNull
        public PaymentMetaData getPaymentMetaData() {
            return paymentMetaData;
        }

        @Override
        public boolean isSeen() {
            return true;
        }
    };
}
Also used : Payment(org.thoughtcrime.securesms.payments.Payment) PaymentMetaData(org.thoughtcrime.securesms.payments.proto.PaymentMetaData) UUID(java.util.UUID) Payee(org.thoughtcrime.securesms.payments.Payee)

Example 17 with Payment

use of org.thoughtcrime.securesms.payments.Payment in project Signal-Android by signalapp.

the class PaymentDetailsFragment method onViewCreated.

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    Toolbar toolbar = view.findViewById(R.id.payments_details_toolbar);
    toolbar.setNavigationOnClickListener(v -> Navigation.findNavController(v).popBackStack());
    PaymentDetailsParcelable details = PaymentDetailsFragmentArgs.fromBundle(requireArguments()).getPaymentDetails();
    AvatarImageView avatar = view.findViewById(R.id.payments_details_avatar);
    BadgeImageView badge = view.findViewById(R.id.payments_details_badge);
    TextView contactFromTo = view.findViewById(R.id.payments_details_contact_to_from);
    MoneyView amount = view.findViewById(R.id.payments_details_amount);
    TextView note = view.findViewById(R.id.payments_details_note);
    TextView status = view.findViewById(R.id.payments_details_status);
    View sentByHeader = view.findViewById(R.id.payments_details_sent_by_header);
    TextView sentBy = view.findViewById(R.id.payments_details_sent_by);
    LearnMoreTextView transactionInfo = view.findViewById(R.id.payments_details_info);
    TextView sentTo = view.findViewById(R.id.payments_details_sent_to_header);
    MoneyView sentToAmount = view.findViewById(R.id.payments_details_sent_to_amount);
    View sentFeeHeader = view.findViewById(R.id.payments_details_sent_fee_header);
    MoneyView sentFeeAmount = view.findViewById(R.id.payments_details_sent_fee_amount);
    Group sentViews = view.findViewById(R.id.payments_details_sent_views);
    View blockHeader = view.findViewById(R.id.payments_details_block_header);
    TextView blockNumber = view.findViewById(R.id.payments_details_block);
    if (details.hasPayment()) {
        Payment payment = details.requirePayment();
        avatar.disableQuickContact();
        avatar.setImageResource(R.drawable.ic_mobilecoin_avatar_24);
        contactFromTo.setText(getContactFromToTextFromDirection(payment.getDirection()));
        amount.setMoney(payment.getAmountPlusFeeWithDirection());
        note.setVisibility(View.GONE);
        status.setText(getStatusFromPayment(payment));
        sentByHeader.setVisibility(View.GONE);
        sentBy.setVisibility(View.GONE);
        transactionInfo.setLearnMoreVisible(true);
        transactionInfo.setText(R.string.PaymentsDetailsFragment__information);
        transactionInfo.setLink(getString(R.string.PaymentsDetailsFragment__learn_more__information));
        sentTo.setVisibility(View.GONE);
        sentToAmount.setVisibility(View.GONE);
        blockHeader.setVisibility(View.VISIBLE);
        blockNumber.setVisibility(View.VISIBLE);
        blockNumber.setText(String.valueOf(payment.getBlockIndex()));
        if (payment.getDirection() == Direction.SENT) {
            sentFeeAmount.setMoney(payment.getFee());
            sentFeeHeader.setVisibility(View.VISIBLE);
            sentFeeAmount.setVisibility(View.VISIBLE);
        }
    } else {
        PaymentsDetailsViewModel viewModel = ViewModelProviders.of(this, new PaymentsDetailsViewModel.Factory(details.requireUuid())).get(PaymentsDetailsViewModel.class);
        viewModel.getViewState().observe(getViewLifecycleOwner(), state -> {
            if (state.getRecipient().getId().isUnknown() || state.getPayment().isDefrag()) {
                avatar.disableQuickContact();
                avatar.setImageResource(R.drawable.ic_mobilecoin_avatar_24);
            } else {
                avatar.setRecipient(state.getRecipient(), true);
                badge.setBadgeFromRecipient(state.getRecipient());
            }
            contactFromTo.setText(describeToOrFrom(state));
            if (state.getPayment().getState() == State.FAILED) {
                amount.setTextColor(ContextCompat.getColor(requireContext(), R.color.signal_text_primary_disabled));
                amount.setMoney(state.getPayment().getAmountPlusFeeWithDirection(), false);
                transactionInfo.setVisibility(View.GONE);
            } else {
                amount.setMoney(state.getPayment().getAmountPlusFeeWithDirection());
                if (state.getPayment().isDefrag()) {
                    transactionInfo.setLearnMoreVisible(true);
                    transactionInfo.setText(R.string.PaymentsDetailsFragment__coin_cleanup_information);
                    transactionInfo.setLink(getString(R.string.PaymentsDetailsFragment__learn_more__cleanup_fee));
                } else {
                    transactionInfo.setLearnMoreVisible(true);
                    transactionInfo.setText(R.string.PaymentsDetailsFragment__information);
                    transactionInfo.setLink(getString(R.string.PaymentsDetailsFragment__learn_more__information));
                }
                transactionInfo.setVisibility(View.VISIBLE);
            }
            String trimmedNote = state.getPayment().getNote().trim();
            note.setText(trimmedNote);
            note.setVisibility(TextUtils.isEmpty(trimmedNote) ? View.GONE : View.VISIBLE);
            status.setText(describeStatus(state.getPayment()));
            sentBy.setText(describeSentBy(state));
            if (state.getPayment().getDirection().isReceived()) {
                sentToAmount.setMoney(Money.MobileCoin.ZERO);
                sentFeeAmount.setMoney(Money.MobileCoin.ZERO);
                sentViews.setVisibility(View.GONE);
            } else {
                sentTo.setText(describeSentTo(state, state.getPayment()));
                sentToAmount.setMoney(state.getPayment().getAmount());
                sentFeeAmount.setMoney(state.getPayment().getFee());
                sentViews.setVisibility(View.VISIBLE);
            }
        });
        viewModel.getPaymentExists().observe(getViewLifecycleOwner(), exists -> {
            if (!exists) {
                Log.w(TAG, "Failed to find payment detail");
                FragmentActivity fragmentActivity = requireActivity();
                fragmentActivity.onBackPressed();
                Toast.makeText(fragmentActivity, R.string.PaymentsDetailsFragment__no_details_available, Toast.LENGTH_SHORT).show();
            }
        });
    }
}
Also used : Group(androidx.constraintlayout.widget.Group) LearnMoreTextView(org.thoughtcrime.securesms.util.views.LearnMoreTextView) AvatarImageView(org.thoughtcrime.securesms.components.AvatarImageView) SpannableString(android.text.SpannableString) BadgeImageView(org.thoughtcrime.securesms.badges.BadgeImageView) View(android.view.View) AvatarImageView(org.thoughtcrime.securesms.components.AvatarImageView) MoneyView(org.thoughtcrime.securesms.payments.MoneyView) TextView(android.widget.TextView) BadgeImageView(org.thoughtcrime.securesms.badges.BadgeImageView) LearnMoreTextView(org.thoughtcrime.securesms.util.views.LearnMoreTextView) FragmentActivity(androidx.fragment.app.FragmentActivity) Payment(org.thoughtcrime.securesms.payments.Payment) MoneyView(org.thoughtcrime.securesms.payments.MoneyView) TextView(android.widget.TextView) LearnMoreTextView(org.thoughtcrime.securesms.util.views.LearnMoreTextView) Toolbar(androidx.appcompat.widget.Toolbar)

Example 18 with Payment

use of org.thoughtcrime.securesms.payments.Payment in project Signal-Android by WhisperSystems.

the class PaymentsRepository method updateDatabaseWithNewBlockInformation.

private void updateDatabaseWithNewBlockInformation(@NonNull List<Payment> reconcileOutput) {
    List<LedgerReconcile.BlockOverridePayment> blockOverridePayments = Stream.of(reconcileOutput).select(LedgerReconcile.BlockOverridePayment.class).toList();
    if (blockOverridePayments.isEmpty()) {
        return;
    }
    Log.i(TAG, String.format(Locale.US, "%d payments have new block index or timestamp information", blockOverridePayments.size()));
    for (LedgerReconcile.BlockOverridePayment blockOverridePayment : blockOverridePayments) {
        Payment inner = blockOverridePayment.getInner();
        boolean override = false;
        if (inner.getBlockIndex() != blockOverridePayment.getBlockIndex()) {
            override = true;
        }
        if (inner.getBlockTimestamp() != blockOverridePayment.getBlockTimestamp()) {
            override = true;
        }
        if (!override) {
            Log.w(TAG, "  Unnecessary");
        } else {
            if (paymentDatabase.updateBlockDetails(inner.getUuid(), blockOverridePayment.getBlockIndex(), blockOverridePayment.getBlockTimestamp())) {
                Log.d(TAG, "  Updated block details for " + inner.getUuid());
            } else {
                Log.w(TAG, "  Failed to update block details for " + inner.getUuid());
            }
        }
    }
}
Also used : Payment(org.thoughtcrime.securesms.payments.Payment) LedgerReconcile(org.thoughtcrime.securesms.payments.reconciliation.LedgerReconcile)

Example 19 with Payment

use of org.thoughtcrime.securesms.payments.Payment in project Signal-Android by WhisperSystems.

the class PaymentDetailsFragment method onViewCreated.

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    Toolbar toolbar = view.findViewById(R.id.payments_details_toolbar);
    toolbar.setNavigationOnClickListener(v -> Navigation.findNavController(v).popBackStack());
    PaymentDetailsParcelable details = PaymentDetailsFragmentArgs.fromBundle(requireArguments()).getPaymentDetails();
    AvatarImageView avatar = view.findViewById(R.id.payments_details_avatar);
    BadgeImageView badge = view.findViewById(R.id.payments_details_badge);
    TextView contactFromTo = view.findViewById(R.id.payments_details_contact_to_from);
    MoneyView amount = view.findViewById(R.id.payments_details_amount);
    TextView note = view.findViewById(R.id.payments_details_note);
    TextView status = view.findViewById(R.id.payments_details_status);
    View sentByHeader = view.findViewById(R.id.payments_details_sent_by_header);
    TextView sentBy = view.findViewById(R.id.payments_details_sent_by);
    LearnMoreTextView transactionInfo = view.findViewById(R.id.payments_details_info);
    TextView sentTo = view.findViewById(R.id.payments_details_sent_to_header);
    MoneyView sentToAmount = view.findViewById(R.id.payments_details_sent_to_amount);
    View sentFeeHeader = view.findViewById(R.id.payments_details_sent_fee_header);
    MoneyView sentFeeAmount = view.findViewById(R.id.payments_details_sent_fee_amount);
    Group sentViews = view.findViewById(R.id.payments_details_sent_views);
    View blockHeader = view.findViewById(R.id.payments_details_block_header);
    TextView blockNumber = view.findViewById(R.id.payments_details_block);
    if (details.hasPayment()) {
        Payment payment = details.requirePayment();
        avatar.disableQuickContact();
        avatar.setImageResource(R.drawable.ic_mobilecoin_avatar_24);
        contactFromTo.setText(getContactFromToTextFromDirection(payment.getDirection()));
        amount.setMoney(payment.getAmountPlusFeeWithDirection());
        note.setVisibility(View.GONE);
        status.setText(getStatusFromPayment(payment));
        sentByHeader.setVisibility(View.GONE);
        sentBy.setVisibility(View.GONE);
        transactionInfo.setLearnMoreVisible(true);
        transactionInfo.setText(R.string.PaymentsDetailsFragment__information);
        transactionInfo.setLink(getString(R.string.PaymentsDetailsFragment__learn_more__information));
        sentTo.setVisibility(View.GONE);
        sentToAmount.setVisibility(View.GONE);
        blockHeader.setVisibility(View.VISIBLE);
        blockNumber.setVisibility(View.VISIBLE);
        blockNumber.setText(String.valueOf(payment.getBlockIndex()));
        if (payment.getDirection() == Direction.SENT) {
            sentFeeAmount.setMoney(payment.getFee());
            sentFeeHeader.setVisibility(View.VISIBLE);
            sentFeeAmount.setVisibility(View.VISIBLE);
        }
    } else {
        PaymentsDetailsViewModel viewModel = ViewModelProviders.of(this, new PaymentsDetailsViewModel.Factory(details.requireUuid())).get(PaymentsDetailsViewModel.class);
        viewModel.getViewState().observe(getViewLifecycleOwner(), state -> {
            if (state.getRecipient().getId().isUnknown() || state.getPayment().isDefrag()) {
                avatar.disableQuickContact();
                avatar.setImageResource(R.drawable.ic_mobilecoin_avatar_24);
            } else {
                avatar.setRecipient(state.getRecipient(), true);
                badge.setBadgeFromRecipient(state.getRecipient());
            }
            contactFromTo.setText(describeToOrFrom(state));
            if (state.getPayment().getState() == State.FAILED) {
                amount.setTextColor(ContextCompat.getColor(requireContext(), R.color.signal_text_primary_disabled));
                amount.setMoney(state.getPayment().getAmountPlusFeeWithDirection(), false);
                transactionInfo.setVisibility(View.GONE);
            } else {
                amount.setMoney(state.getPayment().getAmountPlusFeeWithDirection());
                if (state.getPayment().isDefrag()) {
                    transactionInfo.setLearnMoreVisible(true);
                    transactionInfo.setText(R.string.PaymentsDetailsFragment__coin_cleanup_information);
                    transactionInfo.setLink(getString(R.string.PaymentsDetailsFragment__learn_more__cleanup_fee));
                } else {
                    transactionInfo.setLearnMoreVisible(true);
                    transactionInfo.setText(R.string.PaymentsDetailsFragment__information);
                    transactionInfo.setLink(getString(R.string.PaymentsDetailsFragment__learn_more__information));
                }
                transactionInfo.setVisibility(View.VISIBLE);
            }
            String trimmedNote = state.getPayment().getNote().trim();
            note.setText(trimmedNote);
            note.setVisibility(TextUtils.isEmpty(trimmedNote) ? View.GONE : View.VISIBLE);
            status.setText(describeStatus(state.getPayment()));
            sentBy.setText(describeSentBy(state));
            if (state.getPayment().getDirection().isReceived()) {
                sentToAmount.setMoney(Money.MobileCoin.ZERO);
                sentFeeAmount.setMoney(Money.MobileCoin.ZERO);
                sentViews.setVisibility(View.GONE);
            } else {
                sentTo.setText(describeSentTo(state, state.getPayment()));
                sentToAmount.setMoney(state.getPayment().getAmount());
                sentFeeAmount.setMoney(state.getPayment().getFee());
                sentViews.setVisibility(View.VISIBLE);
            }
        });
        viewModel.getPaymentExists().observe(getViewLifecycleOwner(), exists -> {
            if (!exists) {
                Log.w(TAG, "Failed to find payment detail");
                FragmentActivity fragmentActivity = requireActivity();
                fragmentActivity.onBackPressed();
                Toast.makeText(fragmentActivity, R.string.PaymentsDetailsFragment__no_details_available, Toast.LENGTH_SHORT).show();
            }
        });
    }
}
Also used : Group(androidx.constraintlayout.widget.Group) LearnMoreTextView(org.thoughtcrime.securesms.util.views.LearnMoreTextView) AvatarImageView(org.thoughtcrime.securesms.components.AvatarImageView) SpannableString(android.text.SpannableString) BadgeImageView(org.thoughtcrime.securesms.badges.BadgeImageView) View(android.view.View) AvatarImageView(org.thoughtcrime.securesms.components.AvatarImageView) MoneyView(org.thoughtcrime.securesms.payments.MoneyView) TextView(android.widget.TextView) BadgeImageView(org.thoughtcrime.securesms.badges.BadgeImageView) LearnMoreTextView(org.thoughtcrime.securesms.util.views.LearnMoreTextView) FragmentActivity(androidx.fragment.app.FragmentActivity) Payment(org.thoughtcrime.securesms.payments.Payment) MoneyView(org.thoughtcrime.securesms.payments.MoneyView) TextView(android.widget.TextView) LearnMoreTextView(org.thoughtcrime.securesms.util.views.LearnMoreTextView) Toolbar(androidx.appcompat.widget.Toolbar)

Example 20 with Payment

use of org.thoughtcrime.securesms.payments.Payment in project Signal-Android by WhisperSystems.

the class LedgerReconcileTest method single_unspent_transaction_on_ledger_only.

@Test
public void single_unspent_transaction_on_ledger_only() {
    MobileCoinLedger ledger = ledger(unspentTxo(mob(2.5), keyImage(2), publicKey(3), block(2)));
    List<Payment> payments = reconcile(Collections.emptyList(), new MobileCoinLedgerWrapper(ledger));
    assertEquals(1, payments.size());
    Payment payment = payments.get(0);
    assertEquals(mob(2.5), payment.getAmount());
    assertEquals(mob(2.5), payment.getAmountWithDirection());
    assertEquals(Direction.RECEIVED, payment.getDirection());
    assertEquals(mob(0), payment.getFee());
    assertEquals(Payee.UNKNOWN, payment.getPayee());
    assertEquals(State.SUCCESSFUL, payment.getState());
    assertEquals(UuidUtil.UNKNOWN_UUID, payment.getUuid());
    assertEquals("", payment.getNote());
}
Also used : Payment(org.thoughtcrime.securesms.payments.Payment) MobileCoinLedger(org.thoughtcrime.securesms.payments.proto.MobileCoinLedger) MobileCoinLedgerWrapper(org.thoughtcrime.securesms.payments.MobileCoinLedgerWrapper) Test(org.junit.Test)

Aggregations

Payment (org.thoughtcrime.securesms.payments.Payment)34 MobileCoinLedgerWrapper (org.thoughtcrime.securesms.payments.MobileCoinLedgerWrapper)28 Test (org.junit.Test)24 MobileCoinLedger (org.thoughtcrime.securesms.payments.proto.MobileCoinLedger)22 ByteString (com.google.protobuf.ByteString)4 ArrayList (java.util.ArrayList)4 HashMap (java.util.HashMap)4 ReconstructedPayment (org.thoughtcrime.securesms.payments.ReconstructedPayment)4 PaymentMetaData (org.thoughtcrime.securesms.payments.proto.PaymentMetaData)4 SpannableString (android.text.SpannableString)2 View (android.view.View)2 TextView (android.widget.TextView)2 NonNull (androidx.annotation.NonNull)2 WorkerThread (androidx.annotation.WorkerThread)2 Toolbar (androidx.appcompat.widget.Toolbar)2 Group (androidx.constraintlayout.widget.Group)2 FragmentActivity (androidx.fragment.app.FragmentActivity)2 Collectors (com.annimon.stream.Collectors)2 ComparatorCompat (com.annimon.stream.ComparatorCompat)2 Stream (com.annimon.stream.Stream)2