diff --git a/app/src/main/java/to/bitkit/ext/PaymentFailureReasonExt.kt b/app/src/main/java/to/bitkit/ext/PaymentFailureReasonExt.kt new file mode 100644 index 000000000..49f64498e --- /dev/null +++ b/app/src/main/java/to/bitkit/ext/PaymentFailureReasonExt.kt @@ -0,0 +1,17 @@ +package to.bitkit.ext + +import android.content.Context +import org.lightningdevkit.ldknode.PaymentFailureReason +import to.bitkit.R + +fun PaymentFailureReason?.toUserMessage(context: Context): String = when (this) { + PaymentFailureReason.RECIPIENT_REJECTED -> + context.getString(R.string.wallet__toast_payment_failed_recipient_rejected) + PaymentFailureReason.RETRIES_EXHAUSTED -> + context.getString(R.string.wallet__toast_payment_failed_retries_exhausted) + PaymentFailureReason.ROUTE_NOT_FOUND -> + context.getString(R.string.wallet__toast_payment_failed_route_not_found) + PaymentFailureReason.PAYMENT_EXPIRED -> + context.getString(R.string.wallet__toast_payment_failed_timeout) + else -> context.getString(R.string.wallet__toast_payment_failed_description) +} diff --git a/app/src/main/java/to/bitkit/fcm/WakeNodeWorker.kt b/app/src/main/java/to/bitkit/fcm/WakeNodeWorker.kt index 7702122f1..6097d7f94 100644 --- a/app/src/main/java/to/bitkit/fcm/WakeNodeWorker.kt +++ b/app/src/main/java/to/bitkit/fcm/WakeNodeWorker.kt @@ -23,6 +23,7 @@ import to.bitkit.data.CacheStore import to.bitkit.data.SettingsStore import to.bitkit.di.json import to.bitkit.ext.amountOnClose +import to.bitkit.ext.toUserMessage import to.bitkit.models.BITCOIN_SYMBOL import to.bitkit.models.BlocktankNotificationType import to.bitkit.models.BlocktankNotificationType.cjitPaymentArrived @@ -153,7 +154,7 @@ class WakeNodeWorker @AssistedInject constructor( is Event.PaymentFailed -> { bestAttemptContent = NotificationDetails( title = appContext.getString(R.string.notification__payment_failed_title), - body = "⚡ ${event.reason}", + body = "⚡ ${event.reason.toUserMessage(appContext)}", ) if (notificationType == wakeToTimeout) { diff --git a/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt b/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt index 814bee504..ca380fd56 100644 --- a/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt +++ b/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt @@ -48,6 +48,7 @@ import kotlinx.coroutines.withContext import kotlinx.coroutines.withTimeout import org.lightningdevkit.ldknode.ChannelDataMigration import org.lightningdevkit.ldknode.Event +import org.lightningdevkit.ldknode.PaymentFailureReason import org.lightningdevkit.ldknode.PaymentId import org.lightningdevkit.ldknode.SpendableUtxo import org.lightningdevkit.ldknode.Txid @@ -74,6 +75,7 @@ import to.bitkit.ext.rawId import to.bitkit.ext.removeSpaces import to.bitkit.ext.setClipboardText import to.bitkit.ext.toHex +import to.bitkit.ext.toUserMessage import to.bitkit.ext.totalValue import to.bitkit.ext.watchUntil import to.bitkit.models.FeeRate @@ -537,7 +539,7 @@ class AppViewModel @Inject constructor( event.paymentHash?.let { paymentHash -> activityRepo.handlePaymentEvent(paymentHash) } - notifyPaymentFailed() + notifyPaymentFailed(event.reason) } private suspend fun handlePaymentReceived(event: Event.PaymentReceived) { @@ -625,10 +627,10 @@ class AppViewModel @Inject constructor( ) } - private fun notifyPaymentFailed() = toast( + private fun notifyPaymentFailed(reason: PaymentFailureReason? = null) = toast( type = Toast.ToastType.ERROR, title = context.getString(R.string.wallet__toast_payment_failed_title), - description = context.getString(R.string.wallet__toast_payment_failed_description), + description = reason.toUserMessage(context), testTag = "PaymentFailedToast", ) @@ -1786,7 +1788,7 @@ class AppViewModel @Inject constructor( is Event.PaymentFailed -> { if (event.paymentHash == hash) { - val error = Exception(event.reason?.name ?: "Unknown payment failure reason") + val error = Exception(event.reason.toUserMessage(context)) WatchResult.Complete(Result.failure(error)) } else { WatchResult.Continue() diff --git a/app/src/main/java/to/bitkit/viewmodels/QuickPayViewModel.kt b/app/src/main/java/to/bitkit/viewmodels/QuickPayViewModel.kt index dd0b72457..28da59246 100644 --- a/app/src/main/java/to/bitkit/viewmodels/QuickPayViewModel.kt +++ b/app/src/main/java/to/bitkit/viewmodels/QuickPayViewModel.kt @@ -1,8 +1,10 @@ package to.bitkit.viewmodels +import android.content.Context import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel +import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update @@ -10,6 +12,7 @@ import kotlinx.coroutines.launch import org.lightningdevkit.ldknode.Event import org.lightningdevkit.ldknode.PaymentId import to.bitkit.ext.WatchResult +import to.bitkit.ext.toUserMessage import to.bitkit.ext.watchUntil import to.bitkit.repositories.LightningRepo import to.bitkit.utils.Logger @@ -17,6 +20,7 @@ import javax.inject.Inject @HiltViewModel class QuickPayViewModel @Inject constructor( + @ApplicationContext private val context: Context, private val lightningRepo: LightningRepo, ) : ViewModel() { @@ -90,7 +94,7 @@ class QuickPayViewModel @Inject constructor( is Event.PaymentFailed -> { if (event.paymentHash == hash) { - val error = Exception(event.reason?.name ?: "Unknown payment failure reason") + val error = Exception(event.reason.toUserMessage(context)) WatchResult.Complete(Result.failure(error)) } else { WatchResult.Continue() diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ae59c3971..0d080f226 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -947,6 +947,10 @@ Enter a new tag Previously used tags Your instant payment failed. Please try again. + The recipient rejected this payment. Try a different amount. + Could not find a route with sufficient liquidity. Try a smaller amount or wait and try again. + Could not find a payment path to the recipient. + Payment timed out. Please try again. Payment Failed Your received transaction was replaced by a fee bump Received Transaction Replaced