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));
});
}
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);
}
}
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);
}
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));
}
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;
}
}
Aggregations