Search in sources :

Example 1 with MobileCoinPublicAddress

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

the class ConfirmPaymentRepository method confirmPayment.

@AnyThread
void confirmPayment(@NonNull ConfirmPaymentState state, @NonNull Consumer<ConfirmPaymentResult> consumer) {
    Log.i(TAG, "confirmPayment");
    SignalExecutors.BOUNDED.execute(() -> {
        Balance balance = wallet.getCachedBalance();
        if (state.getTotal().requireMobileCoin().greaterThan(balance.getFullAmount().requireMobileCoin())) {
            Log.w(TAG, "The total was greater than the wallet's balance");
            consumer.accept(new ConfirmPaymentResult.Error());
            return;
        }
        Payee payee = state.getPayee();
        RecipientId recipientId;
        MobileCoinPublicAddress mobileCoinPublicAddress;
        if (payee.hasRecipientId()) {
            recipientId = payee.requireRecipientId();
            try {
                mobileCoinPublicAddress = ProfileUtil.getAddressForRecipient(Recipient.resolved(recipientId));
            } catch (IOException e) {
                Log.w(TAG, "Failed to get address for recipient " + recipientId);
                consumer.accept(new ConfirmPaymentResult.Error());
                return;
            } catch (PaymentsAddressException e) {
                Log.w(TAG, "Failed to get address for recipient " + recipientId);
                consumer.accept(new ConfirmPaymentResult.Error(e.getCode()));
                return;
            }
        } else if (payee.hasPublicAddress()) {
            recipientId = null;
            mobileCoinPublicAddress = payee.requirePublicAddress();
        } else
            throw new AssertionError();
        UUID paymentUuid = PaymentSendJob.enqueuePayment(recipientId, mobileCoinPublicAddress, Util.emptyIfNull(state.getNote()), state.getAmount().requireMobileCoin(), state.getFee().requireMobileCoin());
        Log.i(TAG, "confirmPayment: PaymentSendJob enqueued");
        consumer.accept(new ConfirmPaymentResult.Success(paymentUuid));
    });
}
Also used : RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) IOException(java.io.IOException) PaymentsAddressException(org.thoughtcrime.securesms.payments.PaymentsAddressException) UUID(java.util.UUID) Balance(org.thoughtcrime.securesms.payments.Balance) Payee(org.thoughtcrime.securesms.payments.Payee) MobileCoinPublicAddress(org.thoughtcrime.securesms.payments.MobileCoinPublicAddress) AnyThread(androidx.annotation.AnyThread)

Example 2 with MobileCoinPublicAddress

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

the class ProfileUtil method getAddressForRecipient.

@WorkerThread
@NonNull
public static MobileCoinPublicAddress getAddressForRecipient(@NonNull Recipient recipient) throws IOException, PaymentsAddressException {
    ProfileKey profileKey;
    try {
        profileKey = getProfileKey(recipient);
    } catch (IOException e) {
        Log.w(TAG, "Profile key not available for " + recipient.getId());
        throw new PaymentsAddressException(PaymentsAddressException.Code.NO_PROFILE_KEY);
    }
    ProfileAndCredential profileAndCredential = ProfileUtil.retrieveProfileSync(ApplicationDependencies.getApplication(), recipient, SignalServiceProfile.RequestType.PROFILE);
    SignalServiceProfile profile = profileAndCredential.getProfile();
    byte[] encryptedPaymentsAddress = profile.getPaymentAddress();
    if (encryptedPaymentsAddress == null) {
        Log.w(TAG, "Payments not enabled for " + recipient.getId());
        throw new PaymentsAddressException(PaymentsAddressException.Code.NOT_ENABLED);
    }
    try {
        IdentityKey identityKey = new IdentityKey(Base64.decode(profileAndCredential.getProfile().getIdentityKey()), 0);
        ProfileCipher profileCipher = new ProfileCipher(profileKey);
        byte[] decrypted = profileCipher.decryptWithLength(encryptedPaymentsAddress);
        SignalServiceProtos.PaymentAddress paymentAddress = SignalServiceProtos.PaymentAddress.parseFrom(decrypted);
        byte[] bytes = MobileCoinPublicAddressProfileUtil.verifyPaymentsAddress(paymentAddress, identityKey);
        MobileCoinPublicAddress mobileCoinPublicAddress = MobileCoinPublicAddress.fromBytes(bytes);
        if (mobileCoinPublicAddress == null) {
            throw new PaymentsAddressException(PaymentsAddressException.Code.INVALID_ADDRESS);
        }
        return mobileCoinPublicAddress;
    } catch (InvalidCiphertextException | IOException e) {
        Log.w(TAG, "Could not decrypt payments address, ProfileKey may be outdated for " + recipient.getId(), e);
        throw new PaymentsAddressException(PaymentsAddressException.Code.COULD_NOT_DECRYPT);
    } catch (InvalidKeyException e) {
        Log.w(TAG, "Could not verify payments address due to bad identity key " + recipient.getId(), e);
        throw new PaymentsAddressException(PaymentsAddressException.Code.INVALID_ADDRESS_SIGNATURE);
    }
}
Also used : IdentityKey(org.whispersystems.libsignal.IdentityKey) InvalidCiphertextException(org.whispersystems.signalservice.api.crypto.InvalidCiphertextException) ProfileCipher(org.whispersystems.signalservice.api.crypto.ProfileCipher) ProfileAndCredential(org.whispersystems.signalservice.api.profiles.ProfileAndCredential) IOException(java.io.IOException) PaymentsAddressException(org.thoughtcrime.securesms.payments.PaymentsAddressException) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) ProfileKey(org.signal.zkgroup.profiles.ProfileKey) SignalServiceProfile(org.whispersystems.signalservice.api.profiles.SignalServiceProfile) SignalServiceProtos(org.whispersystems.signalservice.internal.push.SignalServiceProtos) MobileCoinPublicAddress(org.thoughtcrime.securesms.payments.MobileCoinPublicAddress) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Example 3 with MobileCoinPublicAddress

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

the class MessageContentProcessor method handleSynchronizeOutgoingPayment.

private void handleSynchronizeOutgoingPayment(@NonNull SignalServiceContent content, @NonNull OutgoingPaymentMessage outgoingPaymentMessage) {
    RecipientId recipientId = outgoingPaymentMessage.getRecipient().transform(RecipientId::from).orNull();
    long timestamp = outgoingPaymentMessage.getBlockTimestamp();
    if (timestamp == 0) {
        timestamp = System.currentTimeMillis();
    }
    Optional<MobileCoinPublicAddress> address = outgoingPaymentMessage.getAddress().transform(MobileCoinPublicAddress::fromBytes);
    if (!address.isPresent() && recipientId == null) {
        log(content.getTimestamp(), "Inserting defrag");
        address = Optional.of(ApplicationDependencies.getPayments().getWallet().getMobileCoinPublicAddress());
        recipientId = Recipient.self().getId();
    }
    UUID uuid = UUID.randomUUID();
    try {
        SignalDatabase.payments().createSuccessfulPayment(uuid, recipientId, address.get(), timestamp, outgoingPaymentMessage.getBlockIndex(), outgoingPaymentMessage.getNote().or(""), outgoingPaymentMessage.getAmount(), outgoingPaymentMessage.getFee(), outgoingPaymentMessage.getReceipt().toByteArray(), PaymentMetaDataUtil.fromKeysAndImages(outgoingPaymentMessage.getPublicKeys(), outgoingPaymentMessage.getKeyImages()));
    } catch (SerializationException e) {
        warn(content.getTimestamp(), "Ignoring synchronized outgoing payment with bad data.", e);
    }
    log("Inserted synchronized payment " + uuid);
}
Also used : RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) SerializationException(com.mobilecoin.lib.exceptions.SerializationException) UUID(java.util.UUID) MobileCoinPublicAddress(org.thoughtcrime.securesms.payments.MobileCoinPublicAddress)

Example 4 with MobileCoinPublicAddress

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

the class PaymentsAddMoneyRepository method getWalletAddress.

@MainThread
void getWalletAddress(@NonNull AsynchronousCallback.MainThread<AddressAndUri, Error> callback) {
    if (!SignalStore.paymentsValues().mobileCoinPaymentsEnabled()) {
        callback.onError(Error.PAYMENTS_NOT_ENABLED);
    }
    MobileCoinPublicAddress publicAddress = ApplicationDependencies.getPayments().getWallet().getMobileCoinPublicAddress();
    String paymentAddressBase58 = publicAddress.getPaymentAddressBase58();
    Uri paymentAddressUri = publicAddress.getPaymentAddressUri();
    callback.onComplete(new AddressAndUri(paymentAddressBase58, paymentAddressUri));
}
Also used : MobileCoinPublicAddress(org.thoughtcrime.securesms.payments.MobileCoinPublicAddress) Uri(android.net.Uri) MainThread(androidx.annotation.MainThread)

Example 5 with MobileCoinPublicAddress

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

the class PaymentsTransferFragment method next.

private boolean next(@NonNull MobileCoinPublicAddress ownAddress) {
    try {
        String base58Address = address.getText().toString();
        MobileCoinPublicAddress publicAddress = MobileCoinPublicAddress.fromBase58(base58Address);
        if (ownAddress.equals(publicAddress)) {
            new AlertDialog.Builder(requireContext()).setTitle(R.string.PaymentsTransferFragment__invalid_address).setMessage(R.string.PaymentsTransferFragment__you_cant_transfer_to_your_own_signal_wallet_address).setPositiveButton(android.R.string.ok, null).show();
            return false;
        }
        NavDirections action = PaymentsTransferFragmentDirections.actionPaymentsTransferToCreatePayment(new PayeeParcelable(publicAddress)).setFinishOnConfirm(PaymentsTransferFragmentArgs.fromBundle(requireArguments()).getFinishOnConfirm());
        SafeNavigation.safeNavigate(Navigation.findNavController(requireView()), action);
        return true;
    } catch (MobileCoinPublicAddress.AddressException e) {
        Log.w(TAG, "Address is not valid", e);
        new AlertDialog.Builder(requireContext()).setTitle(R.string.PaymentsTransferFragment__invalid_address).setMessage(R.string.PaymentsTransferFragment__check_the_wallet_address).setPositiveButton(android.R.string.ok, null).show();
        return false;
    }
}
Also used : AlertDialog(android.app.AlertDialog) PayeeParcelable(org.thoughtcrime.securesms.payments.preferences.model.PayeeParcelable) MobileCoinPublicAddress(org.thoughtcrime.securesms.payments.MobileCoinPublicAddress) NavDirections(androidx.navigation.NavDirections)

Aggregations

MobileCoinPublicAddress (org.thoughtcrime.securesms.payments.MobileCoinPublicAddress)7 UUID (java.util.UUID)3 RecipientId (org.thoughtcrime.securesms.recipients.RecipientId)3 IOException (java.io.IOException)2 PaymentsAddressException (org.thoughtcrime.securesms.payments.PaymentsAddressException)2 AlertDialog (android.app.AlertDialog)1 Uri (android.net.Uri)1 AnyThread (androidx.annotation.AnyThread)1 MainThread (androidx.annotation.MainThread)1 NonNull (androidx.annotation.NonNull)1 Nullable (androidx.annotation.Nullable)1 WorkerThread (androidx.annotation.WorkerThread)1 NavDirections (androidx.navigation.NavDirections)1 SerializationException (com.mobilecoin.lib.exceptions.SerializationException)1 ProfileKey (org.signal.zkgroup.profiles.ProfileKey)1 PaymentDatabase (org.thoughtcrime.securesms.database.PaymentDatabase)1 NotPushRegisteredException (org.thoughtcrime.securesms.net.NotPushRegisteredException)1 Balance (org.thoughtcrime.securesms.payments.Balance)1 Payee (org.thoughtcrime.securesms.payments.Payee)1 PaymentSubmissionResult (org.thoughtcrime.securesms.payments.PaymentSubmissionResult)1