Skip to content

Commit b769ed3

Browse files
authored
Merge pull request #779 from synonymdev/feat/ldk-vss-settings
feat: vss ldk debug ui
2 parents 4abd8fd + 26b3119 commit b769ed3

9 files changed

Lines changed: 687 additions & 200 deletions

File tree

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

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -836,26 +836,28 @@ class LightningService @Inject constructor(
836836
): ULong {
837837
val node = this.node ?: throw ServiceError.NodeNotSetup()
838838

839-
Logger.verbose(
840-
"Calculating fee for $amountSats sats to $address, ${utxosToSpend?.size} UTXOs, satsPerVByte=$satsPerVByte",
841-
context = TAG,
842-
)
843-
844839
return ServiceQueue.LDK.background {
845-
return@background try {
846-
val fee = node.onchainPayment().calculateTotalFee(
840+
return@background runCatching {
841+
node.onchainPayment().calculateTotalFee(
847842
address = address,
848843
amountSats = amountSats,
849844
feeRate = FeeRate.fromSatPerVbUnchecked(satsPerVByte),
850845
utxosToSpend = utxosToSpend,
851-
)
852-
Logger.debug(
853-
"Calculated fee='$fee' for $amountSats sats to $address, satsPerVByte=$satsPerVByte",
846+
).also {
847+
Logger.debug(
848+
"Calculated fee='$it' for $amountSats sats to $address, satsPerVByte=$satsPerVByte",
849+
context = TAG,
850+
)
851+
}
852+
}.getOrElse {
853+
Logger.warn(
854+
"Error calculating fee for $amountSats sats to $address, " +
855+
"${utxosToSpend?.size} UTXOs, satsPerVByte=$satsPerVByte",
854856
context = TAG,
857+
e = it,
855858
)
856-
fee
857-
} catch (e: NodeException) {
858-
throw LdkError(e)
859+
860+
throw if (it is NodeException) LdkError(it) else it
859861
}
860862
}
861863
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import to.bitkit.ui.screens.settings.DevSettingsScreen
7070
import to.bitkit.ui.screens.settings.FeeSettingsScreen
7171
import to.bitkit.ui.screens.settings.LdkDebugScreen
7272
import to.bitkit.ui.screens.settings.ProbingToolScreen
73+
import to.bitkit.ui.screens.settings.VssDebugScreen
7374
import to.bitkit.ui.screens.shop.ShopIntroScreen
7475
import to.bitkit.ui.screens.shop.shopDiscover.ShopDiscoverScreen
7576
import to.bitkit.ui.screens.shop.shopWebView.ShopWebViewScreen
@@ -891,6 +892,9 @@ private fun NavGraphBuilder.settings(
891892
composableWithDefaultTransitions<Routes.LdkDebug> {
892893
LdkDebugScreen(navController)
893894
}
895+
composableWithDefaultTransitions<Routes.VssDebug> {
896+
VssDebugScreen(navController)
897+
}
894898
composableWithDefaultTransitions<Routes.ProbingTool> {
895899
ProbingToolScreen(it.savedStateHandle, navController)
896900
}
@@ -1842,6 +1846,9 @@ sealed interface Routes {
18421846
@Serializable
18431847
data object LdkDebug : Routes
18441848

1849+
@Serializable
1850+
data object VssDebug : Routes
1851+
18451852
@Serializable
18461853
data object ProbingTool : Routes
18471854

app/src/main/java/to/bitkit/ui/components/settings/SettingsTextButtonRow.kt

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Row
66
import androidx.compose.foundation.layout.Spacer
77
import androidx.compose.foundation.layout.fillMaxWidth
88
import androidx.compose.foundation.layout.height
9+
import androidx.compose.foundation.layout.heightIn
910
import androidx.compose.foundation.layout.padding
1011
import androidx.compose.foundation.layout.size
1112
import androidx.compose.material3.HorizontalDivider
@@ -37,6 +38,7 @@ fun SettingsTextButtonRow(
3738
description: String? = null,
3839
iconRes: Int? = null,
3940
iconTint: Color = Color.Unspecified,
41+
iconSize: Dp = 32.dp,
4042
enabled: Boolean = true,
4143
height: Dp = 52.dp,
4244
showDivider: Boolean = true,
@@ -51,15 +53,15 @@ fun SettingsTextButtonRow(
5153
verticalAlignment = Alignment.CenterVertically,
5254
modifier = Modifier
5355
.fillMaxWidth()
54-
.height(height)
56+
.heightIn(min = height)
5557
.clickableAlpha(onClick = if (enabled) onClick else null)
5658
) {
5759
if (iconRes != null) {
5860
Icon(
5961
painter = painterResource(iconRes),
6062
contentDescription = null,
6163
tint = iconTint,
62-
modifier = Modifier.size(32.dp),
64+
modifier = Modifier.size(iconSize),
6365
)
6466
HorizontalSpacer(10.dp)
6567
}
@@ -90,6 +92,7 @@ fun SettingsTextButtonRow(
9092
}
9193
}
9294

95+
@Suppress("SpellCheckingInspection")
9396
@Preview(showSystemUi = true)
9497
@Composable
9598
private fun Preview() {
@@ -116,6 +119,27 @@ private fun Preview() {
116119
value = "Value",
117120
onClick = {},
118121
)
122+
SettingsTextButtonRow(
123+
title = "Title",
124+
description = "Duis incididunt voluptate Lorem consectetur incididunt. Sint eiusmod amet aute " +
125+
"adipisicing laboris deserunt cupidatat ut.",
126+
value = "Value",
127+
onClick = {},
128+
trailingContent = {
129+
Icon(
130+
painter = painterResource(R.drawable.ic_share_purple),
131+
contentDescription = null,
132+
tint = Colors.White,
133+
modifier = Modifier.size(24.dp),
134+
)
135+
Icon(
136+
painter = painterResource(R.drawable.ic_trash),
137+
contentDescription = null,
138+
tint = Colors.Red,
139+
modifier = Modifier.size(24.dp),
140+
)
141+
}
142+
)
119143
SettingsTextButtonRow(
120144
title = "Disabled",
121145
iconRes = R.drawable.ic_settings,

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ fun DevSettingsScreen(
5151
) {
5252
SettingsButtonRow("Fee Settings") { navController.navigate(Routes.FeeSettings) }
5353
SettingsButtonRow("Channel Orders") { navController.navigate(Routes.ChannelOrdersSettings) }
54-
SettingsButtonRow("LDK Debug") { navController.navigate(Routes.LdkDebug) }
54+
SettingsButtonRow("LDK") { navController.navigate(Routes.LdkDebug) }
55+
SettingsButtonRow("VSS") { navController.navigate(Routes.VssDebug) }
5556
SettingsButtonRow("Probing Tool") { navController.navigate(Routes.ProbingTool) }
5657

5758
SectionHeader("LOGS")

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

Lines changed: 5 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
package to.bitkit.ui.screens.settings
22

3-
import androidx.compose.animation.AnimatedVisibility
4-
import androidx.compose.animation.expandVertically
5-
import androidx.compose.animation.fadeIn
6-
import androidx.compose.animation.fadeOut
7-
import androidx.compose.animation.shrinkVertically
83
import androidx.compose.foundation.layout.Arrangement
94
import androidx.compose.foundation.layout.Column
105
import androidx.compose.foundation.layout.PaddingValues
@@ -15,39 +10,33 @@ import androidx.compose.foundation.layout.height
1510
import androidx.compose.foundation.layout.padding
1611
import androidx.compose.foundation.rememberScrollState
1712
import androidx.compose.foundation.verticalScroll
18-
import androidx.compose.material3.Icon
1913
import androidx.compose.runtime.Composable
2014
import androidx.compose.runtime.getValue
2115
import androidx.compose.runtime.mutableStateOf
2216
import androidx.compose.runtime.remember
2317
import androidx.compose.runtime.setValue
2418
import androidx.compose.ui.Modifier
2519
import androidx.compose.ui.platform.LocalContext
26-
import androidx.compose.ui.res.painterResource
2720
import androidx.compose.ui.tooling.preview.Preview
2821
import androidx.compose.ui.unit.dp
2922
import androidx.core.content.FileProvider
3023
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
3124
import androidx.lifecycle.compose.collectAsStateWithLifecycle
3225
import androidx.navigation.NavController
33-
import com.synonym.vssclient.KeyVersion
3426
import to.bitkit.R
3527
import to.bitkit.env.Env
36-
import to.bitkit.models.BackupCategory
3728
import to.bitkit.ui.components.ButtonSize
3829
import to.bitkit.ui.components.PrimaryButton
3930
import to.bitkit.ui.components.SecondaryButton
4031
import to.bitkit.ui.components.TextInput
4132
import to.bitkit.ui.components.settings.SectionFooter
4233
import to.bitkit.ui.components.settings.SectionHeader
4334
import to.bitkit.ui.components.settings.SettingsTextButtonRow
44-
import to.bitkit.ui.scaffold.AppAlertDialog
4535
import to.bitkit.ui.scaffold.AppTopBar
4636
import to.bitkit.ui.scaffold.DrawerNavIcon
4737
import to.bitkit.ui.scaffold.ScreenColumn
4838
import to.bitkit.ui.shared.util.shareFile
4939
import to.bitkit.ui.theme.AppThemeSurface
50-
import to.bitkit.ui.theme.Colors
5140
import to.bitkit.viewmodels.LdkDebugUiState
5241
import to.bitkit.viewmodels.LdkDebugViewModel
5342
import java.io.File
@@ -67,9 +56,6 @@ fun LdkDebugScreen(
6756
onPasteAndAddPeer = viewModel::pasteAndAddPeer,
6857
onLogNetworkGraphInfo = viewModel::logNetworkGraphInfo,
6958
onExportNetworkGraph = viewModel::exportNetworkGraph,
70-
onListVssKeys = viewModel::listVssKeys,
71-
onDeleteVssKey = viewModel::deleteVssKey,
72-
onDeleteAllVssKeys = viewModel::deleteAllVssKeys,
7359
onRestartNode = viewModel::restartNode,
7460
)
7561
}
@@ -83,13 +69,9 @@ private fun LdkDebugContent(
8369
onPasteAndAddPeer: () -> Unit,
8470
onLogNetworkGraphInfo: () -> Unit,
8571
onExportNetworkGraph: (onFileReady: (File) -> Unit) -> Unit,
86-
onListVssKeys: () -> Unit,
87-
onDeleteVssKey: (String) -> Unit,
88-
onDeleteAllVssKeys: () -> Unit,
8972
onRestartNode: () -> Unit,
9073
) {
9174
val context = LocalContext.current
92-
var showDeleteAllConfirmation by remember { mutableStateOf(false) }
9375

9476
ScreenColumn {
9577
AppTopBar(
@@ -136,6 +118,7 @@ private fun LdkDebugContent(
136118
SettingsTextButtonRow(
137119
title = "Log Graph Info",
138120
iconRes = R.drawable.ic_list,
121+
iconSize = 24.dp,
139122
enabled = !uiState.isLoading,
140123
onClick = onLogNetworkGraphInfo,
141124
)
@@ -148,6 +131,7 @@ private fun LdkDebugContent(
148131
SettingsTextButtonRow(
149132
title = "Export to File",
150133
iconRes = R.drawable.ic_share,
134+
iconSize = 24.dp,
151135
enabled = !uiState.isLoading,
152136
onClick = {
153137
onExportNetworkGraph { file ->
@@ -157,113 +141,34 @@ private fun LdkDebugContent(
157141
},
158142
)
159143

160-
SectionHeader("VSS")
161-
SettingsTextButtonRow(
162-
title = "List Keys",
163-
iconRes = R.drawable.ic_stack,
164-
value = if (uiState.vssKeys.isNotEmpty()) "${uiState.vssKeys.size} found" else "",
165-
enabled = !uiState.isLoading,
166-
onClick = onListVssKeys,
167-
)
168-
AnimatedVisibility(
169-
visible = uiState.vssKeys.isNotEmpty(),
170-
enter = fadeIn() + expandVertically(),
171-
exit = fadeOut() + shrinkVertically(),
172-
) {
173-
Column {
174-
uiState.vssKeys.take(MAX_VSS_KEYS_DISPLAY).forEach { keyVersion ->
175-
SettingsTextButtonRow(
176-
title = keyVersion.key,
177-
iconRes = R.drawable.ic_tag,
178-
value = "v${keyVersion.version}",
179-
enabled = !uiState.isLoading,
180-
height = 44.dp,
181-
trailingContent = {
182-
SecondaryButton(
183-
text = null,
184-
onClick = { onDeleteVssKey(keyVersion.key) },
185-
enabled = !uiState.isLoading,
186-
size = ButtonSize.Small,
187-
fullWidth = false,
188-
icon = {
189-
Icon(
190-
painter = painterResource(R.drawable.ic_trash),
191-
contentDescription = "Delete key",
192-
tint = Colors.Red,
193-
)
194-
},
195-
)
196-
},
197-
)
198-
}
199-
if (uiState.vssKeys.size > MAX_VSS_KEYS_DISPLAY) {
200-
SectionFooter("…and ${uiState.vssKeys.size - MAX_VSS_KEYS_DISPLAY} more")
201-
}
202-
}
203-
}
204-
SettingsTextButtonRow(
205-
title = "Delete All",
206-
iconRes = R.drawable.ic_trash,
207-
enabled = !uiState.isLoading && uiState.vssKeys.isNotEmpty(),
208-
onClick = { showDeleteAllConfirmation = true },
209-
)
210-
211144
SectionHeader("NODE")
212145
SettingsTextButtonRow(
213146
title = "Restart",
214147
iconRes = R.drawable.ic_arrow_clockwise,
148+
iconSize = 24.dp,
215149
enabled = !uiState.isLoading,
216150
onClick = onRestartNode,
217151
)
218152

219153
Spacer(modifier = Modifier.height(32.dp))
220154
}
221155
}
222-
223-
if (showDeleteAllConfirmation) {
224-
AppAlertDialog(
225-
title = "Delete All VSS Keys?",
226-
text = "This will permanently delete all ${uiState.vssKeys.size} VSS key(s). This action cannot be undone.",
227-
confirmText = "Delete All",
228-
onConfirm = {
229-
showDeleteAllConfirmation = false
230-
onDeleteAllVssKeys()
231-
},
232-
onDismiss = { showDeleteAllConfirmation = false },
233-
)
234-
}
235156
}
236157

237-
private const val MAX_VSS_KEYS_DISPLAY = 10
238-
239158
@Preview(showSystemUi = true)
240159
@Composable
241160
private fun Preview() {
242-
val vssKeys = BackupCategory.entries.mapIndexed { i, key -> KeyVersion(key.name, (i + 1).toLong()) }
243-
var uiState by remember {
244-
mutableStateOf(
245-
LdkDebugUiState(
246-
// vssKeys = vssKeys,
247-
)
248-
)
249-
}
250-
251-
fun listVssKeys() {
252-
uiState = uiState.copy(vssKeys = vssKeys)
253-
}
161+
var uiState by remember { mutableStateOf(LdkDebugUiState()) }
254162

255163
AppThemeSurface {
256164
LdkDebugContent(
257165
uiState = uiState,
258166
onBackClick = {},
259-
onNodeUriChange = {},
167+
onNodeUriChange = { uiState = uiState.copy(nodeUri = it) },
260168
onAddPeer = {},
261169
onPasteAndAddPeer = {},
262170
onLogNetworkGraphInfo = {},
263171
onExportNetworkGraph = {},
264-
onListVssKeys = ::listVssKeys,
265-
onDeleteVssKey = {},
266-
onDeleteAllVssKeys = {},
267172
onRestartNode = {},
268173
)
269174
}

0 commit comments

Comments
 (0)