Skip to content

Commit a7e9c33

Browse files
committed
feat: Add ldk debug dev settings screen
1 parent 79c9fdc commit a7e9c33

File tree

11 files changed

+864
-21
lines changed

11 files changed

+864
-21
lines changed

app/src/main/java/to/bitkit/data/backup/VssBackupClient.kt

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package to.bitkit.data.backup
22

3+
import com.synonym.vssclient.KeyVersion
34
import com.synonym.vssclient.VssItem
5+
import com.synonym.vssclient.vssDelete
46
import com.synonym.vssclient.vssGet
7+
import com.synonym.vssclient.vssListKeys
58
import com.synonym.vssclient.vssNewClient
69
import com.synonym.vssclient.vssNewClientWithLnurlAuth
710
import com.synonym.vssclient.vssStore
@@ -106,6 +109,52 @@ class VssBackupClient @Inject constructor(
106109
}
107110
}
108111

112+
suspend fun listKeys(prefix: String? = null): Result<List<KeyVersion>> = withContext(ioDispatcher) {
113+
isSetup.await()
114+
Logger.verbose("VSS 'listKeys' call with prefix: '$prefix'", context = TAG)
115+
runCatching {
116+
vssListKeys(prefix = prefix)
117+
}.onSuccess {
118+
Logger.verbose("VSS 'listKeys' success - found ${it.size} key(s)", context = TAG)
119+
}.onFailure { e ->
120+
Logger.verbose("VSS 'listKeys' error", e = e, context = TAG)
121+
}
122+
}
123+
124+
suspend fun deleteObject(key: String): Result<Boolean> = withContext(ioDispatcher) {
125+
isSetup.await()
126+
Logger.verbose("VSS 'deleteObject' call for '$key'", context = TAG)
127+
runCatching {
128+
vssDelete(key = key)
129+
}.onSuccess { wasDeleted ->
130+
if (wasDeleted) {
131+
Logger.verbose("VSS 'deleteObject' success for '$key' - key was deleted", context = TAG)
132+
} else {
133+
Logger.verbose("VSS 'deleteObject' success for '$key' - key did not exist", context = TAG)
134+
}
135+
}.onFailure { e ->
136+
Logger.verbose("VSS 'deleteObject' error for '$key'", e = e, context = TAG)
137+
}
138+
}
139+
140+
suspend fun deleteAllKeys(): Result<Int> = withContext(ioDispatcher) {
141+
isSetup.await()
142+
Logger.verbose("VSS 'deleteAllKeys' call", context = TAG)
143+
runCatching {
144+
val keys = vssListKeys(prefix = null)
145+
var deletedCount = 0
146+
for (keyVersion in keys) {
147+
val wasDeleted = vssDelete(key = keyVersion.key)
148+
if (wasDeleted) deletedCount++
149+
}
150+
deletedCount
151+
}.onSuccess {
152+
Logger.verbose("VSS 'deleteAllKeys' success - deleted $it key(s)", context = TAG)
153+
}.onFailure { e ->
154+
Logger.verbose("VSS 'deleteAllKeys' error", e = e, context = TAG)
155+
}
156+
}
157+
109158
companion object Companion {
110159
private const val TAG = "VssBackupClient"
111160
}

app/src/main/java/to/bitkit/ext/PeerDetails.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package to.bitkit.ext
22

3+
import com.synonym.bitkitcore.ILspNode
34
import org.lightningdevkit.ldknode.PeerDetails
45

56
val PeerDetails.host get() = address.substringBefore(":")
@@ -35,3 +36,15 @@ fun PeerDetails.Companion.from(nodeId: String, host: String, port: String) = Pee
3536
isConnected = false,
3637
isPersisted = false,
3738
)
39+
40+
fun ILspNode.toPeerDetails(): PeerDetails? {
41+
val address = connectionStrings.firstOrNull() ?: return null
42+
return PeerDetails(
43+
nodeId = pubkey,
44+
address = address,
45+
isConnected = false,
46+
isPersisted = false,
47+
)
48+
}
49+
50+
fun List<ILspNode>.toPeerDetailsList(): List<PeerDetails> = mapNotNull { it.toPeerDetails() }

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

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import to.bitkit.di.BgDispatcher
4646
import to.bitkit.env.Env
4747
import to.bitkit.ext.getSatsPerVByteFor
4848
import to.bitkit.ext.nowTimestamp
49+
import to.bitkit.ext.toPeerDetailsList
4950
import to.bitkit.models.CoinSelectionPreference
5051
import to.bitkit.models.NodeLifecycleState
5152
import to.bitkit.models.OpenChannelResult
@@ -170,14 +171,25 @@ class LightningRepo @Inject constructor(
170171
customRgsServerUrl: String? = null,
171172
) = withContext(bgDispatcher) {
172173
return@withContext try {
173-
lightningService.setup(walletIndex, customServerUrl, customRgsServerUrl)
174+
val trustedPeers = getTrustedPeersFromBlocktank()
175+
lightningService.setup(walletIndex, customServerUrl, customRgsServerUrl, trustedPeers)
174176
Result.success(Unit)
175177
} catch (e: Throwable) {
176178
Logger.error("Node setup error", e, context = TAG)
177179
Result.failure(e)
178180
}
179181
}
180182

183+
private suspend fun getTrustedPeersFromBlocktank(): List<PeerDetails>? = runCatching {
184+
val info = coreService.blocktank.info(refresh = false)
185+
?: coreService.blocktank.info(refresh = true)
186+
info?.nodes?.toPeerDetailsList()?.also {
187+
Logger.info("Loaded ${it.size} trusted peers from blocktank", context = TAG)
188+
}
189+
}.onFailure {
190+
Logger.warn("Failed to get trusted peers from blocktank", e = it, context = TAG)
191+
}.getOrNull()
192+
181193
@Suppress("LongMethod", "LongParameterList")
182194
suspend fun start(
183195
walletIndex: Int = 0,
@@ -989,6 +1001,29 @@ class LightningRepo @Inject constructor(
9891001
}
9901002
}
9911003

1004+
// region debug
1005+
fun getNetworkGraphInfo() = lightningService.getNetworkGraphInfo()
1006+
1007+
suspend fun exportNetworkGraphToFile(outputDir: String): Result<java.io.File> =
1008+
executeWhenNodeRunning("exportNetworkGraphToFile") {
1009+
lightningService.exportNetworkGraphToFile(outputDir)
1010+
}
1011+
1012+
suspend fun restartNode(): Result<Unit> = withContext(bgDispatcher) {
1013+
Logger.info("Restarting LDK node", context = TAG)
1014+
stop().onFailure {
1015+
Logger.error("Failed to stop node during restart", it, context = TAG)
1016+
return@withContext Result.failure(it)
1017+
}
1018+
start(shouldRetry = false).onFailure {
1019+
Logger.error("Failed to start node during restart", it, context = TAG)
1020+
return@withContext Result.failure(it)
1021+
}
1022+
Logger.info("LDK node restarted successfully", context = TAG)
1023+
Result.success(Unit)
1024+
}
1025+
// endregion
1026+
9921027
companion object {
9931028
private const val TAG = "LightningRepo"
9941029
private const val CHANNEL_ID_PREVIEW_LENGTH = 10

0 commit comments

Comments
 (0)