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