Skip to content

Commit 5df97aa

Browse files
committed
Merge branch 'master' into refactor/secure-strings
2 parents 042d3b0 + cd71e00 commit 5df97aa

File tree

18 files changed

+570
-44
lines changed

18 files changed

+570
-44
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package to.bitkit.ext
2+
3+
import android.content.Context
4+
import org.lightningdevkit.ldknode.PaymentFailureReason
5+
import to.bitkit.R
6+
7+
fun PaymentFailureReason?.toUserMessage(context: Context): String = when (this) {
8+
PaymentFailureReason.RECIPIENT_REJECTED ->
9+
context.getString(R.string.wallet__toast_payment_failed_recipient_rejected)
10+
PaymentFailureReason.RETRIES_EXHAUSTED ->
11+
context.getString(R.string.wallet__toast_payment_failed_retries_exhausted)
12+
PaymentFailureReason.ROUTE_NOT_FOUND ->
13+
context.getString(R.string.wallet__toast_payment_failed_route_not_found)
14+
PaymentFailureReason.PAYMENT_EXPIRED ->
15+
context.getString(R.string.wallet__toast_payment_failed_timeout)
16+
else -> context.getString(R.string.wallet__toast_payment_failed_description)
17+
}

app/src/main/java/to/bitkit/fcm/WakeNodeWorker.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import to.bitkit.data.CacheStore
2323
import to.bitkit.data.SettingsStore
2424
import to.bitkit.di.json
2525
import to.bitkit.ext.amountOnClose
26+
import to.bitkit.ext.toUserMessage
2627
import to.bitkit.models.BITCOIN_SYMBOL
2728
import to.bitkit.models.BlocktankNotificationType
2829
import to.bitkit.models.BlocktankNotificationType.cjitPaymentArrived
@@ -153,7 +154,7 @@ class WakeNodeWorker @AssistedInject constructor(
153154
is Event.PaymentFailed -> {
154155
bestAttemptContent = NotificationDetails(
155156
title = appContext.getString(R.string.notification__payment_failed_title),
156-
body = "${event.reason}",
157+
body = "${event.reason.toUserMessage(appContext)}",
157158
)
158159

159160
if (notificationType == wakeToTimeout) {

app/src/main/java/to/bitkit/repositories/BlocktankRepo.kt

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@ class BlocktankRepo @Inject constructor(
134134
}
135135
}
136136

137-
suspend fun refreshOrders() = withContext(bgDispatcher) {
138-
if (isRefreshing) return@withContext
137+
suspend fun refreshOrders(): Result<Unit> = withContext(bgDispatcher) {
138+
if (isRefreshing) return@withContext Result.success(Unit)
139139
isRefreshing = true
140140

141141
runCatching {
@@ -172,11 +172,9 @@ class BlocktankRepo @Inject constructor(
172172
context = TAG
173173
)
174174
openChannelWithPaidOrders()
175-
}.onFailure {
176-
Logger.error("Failed to refresh orders", it, context = TAG)
175+
}.also {
176+
isRefreshing = false
177177
}
178-
179-
isRefreshing = false
180178
}
181179

182180
suspend fun refreshMinCjitSats() = withContext(bgDispatcher) {
@@ -303,7 +301,7 @@ class BlocktankRepo @Inject constructor(
303301
): Result<IBtOrder?> = withContext(bgDispatcher) {
304302
runCatching {
305303
if (refresh) {
306-
refreshOrders()
304+
refreshOrders().getOrThrow()
307305
}
308306
val order = _blocktankState.value.orders.find { it.id == orderId }
309307
return@runCatching order

app/src/main/java/to/bitkit/repositories/LightningRepo.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import kotlinx.coroutines.withTimeoutOrNull
3131
import org.lightningdevkit.ldknode.Address
3232
import org.lightningdevkit.ldknode.BalanceDetails
3333
import org.lightningdevkit.ldknode.BestBlock
34+
import org.lightningdevkit.ldknode.Bolt11Invoice
3435
import org.lightningdevkit.ldknode.ChannelConfig
3536
import org.lightningdevkit.ldknode.ChannelDataMigration
3637
import org.lightningdevkit.ldknode.ChannelDetails
@@ -1040,6 +1041,23 @@ class LightningRepo @Inject constructor(
10401041
}
10411042
// endregion
10421043

1044+
// region probing
1045+
suspend fun sendProbeForInvoice(bolt11: String, amountSats: ULong? = null): Result<Unit> =
1046+
executeWhenNodeRunning("sendProbeForInvoice") {
1047+
runCatching {
1048+
val invoice = Bolt11Invoice.fromStr(bolt11)
1049+
if (amountSats != null) {
1050+
val amountMsat = amountSats * 1000u
1051+
lightningService.sendProbesUsingAmount(invoice, amountMsat)
1052+
} else {
1053+
lightningService.sendProbes(invoice)
1054+
}
1055+
}.getOrElse {
1056+
Result.failure(it)
1057+
}
1058+
}
1059+
// endregion
1060+
10431061
suspend fun restartNode(): Result<Unit> = withContext(bgDispatcher) {
10441062
Logger.info("Restarting node", context = TAG)
10451063
stop().onFailure {

app/src/main/java/to/bitkit/services/LightningService.kt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,34 @@ class LightningService @Inject constructor(
598598
}
599599
// endregion
600600

601+
// region probing
602+
suspend fun sendProbes(invoice: Bolt11Invoice): Result<Unit> {
603+
val node = this.node ?: throw ServiceError.NodeNotSetup()
604+
605+
return ServiceQueue.LDK.background {
606+
runCatching {
607+
node.bolt11Payment().sendProbes(invoice, null)
608+
Result.success(Unit)
609+
}.getOrElse {
610+
Result.failure(if (it is NodeException) LdkError(it) else it)
611+
}
612+
}
613+
}
614+
615+
suspend fun sendProbesUsingAmount(invoice: Bolt11Invoice, amountMsat: ULong): Result<Unit> {
616+
val node = this.node ?: throw ServiceError.NodeNotSetup()
617+
618+
return ServiceQueue.LDK.background {
619+
runCatching {
620+
node.bolt11Payment().sendProbesUsingAmount(invoice, amountMsat, null)
621+
Result.success(Unit)
622+
}.getOrElse {
623+
Result.failure(if (it is NodeException) LdkError(it) else it)
624+
}
625+
}
626+
}
627+
// endregion
628+
601629
// region utxo selection
602630
suspend fun listSpendableOutputs(): Result<List<SpendableUtxo>> {
603631
val node = this.node ?: throw ServiceError.NodeNotSetup()

app/src/main/java/to/bitkit/ui/ContentView.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ import to.bitkit.ui.screens.scanner.SCAN_REQUEST_KEY
6969
import to.bitkit.ui.screens.settings.DevSettingsScreen
7070
import to.bitkit.ui.screens.settings.FeeSettingsScreen
7171
import to.bitkit.ui.screens.settings.LdkDebugScreen
72+
import to.bitkit.ui.screens.settings.ProbingToolScreen
7273
import to.bitkit.ui.screens.shop.ShopIntroScreen
7374
import to.bitkit.ui.screens.shop.shopDiscover.ShopDiscoverScreen
7475
import to.bitkit.ui.screens.shop.shopWebView.ShopWebViewScreen
@@ -890,6 +891,9 @@ private fun NavGraphBuilder.settings(
890891
composableWithDefaultTransitions<Routes.LdkDebug> {
891892
LdkDebugScreen(navController)
892893
}
894+
composableWithDefaultTransitions<Routes.ProbingTool> {
895+
ProbingToolScreen(navController)
896+
}
893897
composableWithDefaultTransitions<Routes.FeeSettings> {
894898
FeeSettingsScreen(navController)
895899
}
@@ -1836,6 +1840,9 @@ sealed interface Routes {
18361840
@Serializable
18371841
data object LdkDebug : Routes
18381842

1843+
@Serializable
1844+
data object ProbingTool : Routes
1845+
18391846
@Serializable
18401847
data object FeeSettings : Routes
18411848

app/src/main/java/to/bitkit/ui/screens/settings/DevSettingsScreen.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ fun DevSettingsScreen(
5252
SettingsButtonRow("Fee Settings") { navController.navigate(Routes.FeeSettings) }
5353
SettingsButtonRow("Channel Orders") { navController.navigate(Routes.ChannelOrdersSettings) }
5454
SettingsButtonRow("LDK Debug") { navController.navigate(Routes.LdkDebug) }
55+
SettingsButtonRow("Probing Tool") { navController.navigate(Routes.ProbingTool) }
5556

5657
SectionHeader("LOGS")
5758
SettingsButtonRow("Logs") { navController.navigate(Routes.Logs) }

0 commit comments

Comments
 (0)