Skip to content

Commit 258319a

Browse files
authored
Merge branch 'master' into refactor/lsp-calcs
2 parents 782b0cf + 4c86792 commit 258319a

File tree

13 files changed

+375
-357
lines changed

13 files changed

+375
-357
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ fun Instant.formatted(pattern: String = DatePattern.DATE_TIME): String {
3939
return dateTime.format(formatter)
4040
}
4141

42+
fun ULong?.formatToString(pattern: String = DatePattern.DATE_TIME): String? {
43+
return this?.let { Instant.ofEpochSecond(toLong()).formatted(pattern) }
44+
}
45+
4246
fun Long.toTimeUTC(): String {
4347
val instant = Instant.ofEpochMilli(this)
4448
val dateTime = LocalDateTime.ofInstant(instant, ZoneId.of("UTC"))

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import kotlinx.coroutines.flow.update
1515
import kotlinx.coroutines.launch
1616
import kotlinx.coroutines.withContext
1717
import org.lightningdevkit.ldknode.Event
18+
import org.lightningdevkit.ldknode.WordCount
1819
import to.bitkit.data.CacheStore
1920
import to.bitkit.data.SettingsStore
2021
import to.bitkit.data.keychain.Keychain
@@ -564,7 +565,7 @@ class WalletRepo @Inject constructor(
564565
}
565566

566567
private fun generateEntropyMnemonic(): String {
567-
return org.lightningdevkit.ldknode.generateEntropyMnemonic()
568+
return org.lightningdevkit.ldknode.generateEntropyMnemonic(wordCount = WordCount.WORDS12)
568569
}
569570

570571
private companion object {

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

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import org.lightningdevkit.ldknode.ElectrumSyncConfig
2424
import org.lightningdevkit.ldknode.Event
2525
import org.lightningdevkit.ldknode.FeeRate
2626
import org.lightningdevkit.ldknode.Node
27+
import org.lightningdevkit.ldknode.NodeEntropy
2728
import org.lightningdevkit.ldknode.NodeException
2829
import org.lightningdevkit.ldknode.NodeStatus
2930
import org.lightningdevkit.ldknode.PaymentDetails
@@ -78,15 +79,29 @@ class LightningService @Inject constructor(
7879
customServerUrl: String? = null,
7980
customRgsServerUrl: String? = null,
8081
) {
81-
val mnemonic = keychain.loadString(Keychain.Key.BIP39_MNEMONIC.name) ?: throw ServiceError.MnemonicNotFound
82-
val passphrase = keychain.loadString(Keychain.Key.BIP39_PASSPHRASE.name)
82+
Logger.debug("Building node…")
8383

84-
// TODO get trustedLnPeers from blocktank info
85-
this.trustedPeers = Env.trustedLnPeers
84+
val config = config(walletIndex)
85+
node = build(
86+
walletIndex,
87+
customServerUrl,
88+
customRgsServerUrl,
89+
config,
90+
)
91+
92+
Logger.info("LDK node setup")
93+
}
94+
95+
private fun config(
96+
walletIndex: Int,
97+
): Config {
8698
val dirPath = Env.ldkStoragePath(walletIndex)
8799

100+
// TODO get trustedLnPeers from blocktank info
101+
this.trustedPeers = Env.trustedLnPeers
88102
val trustedPeerNodeIds = trustedPeers.map { it.nodeId }
89-
val config = defaultConfig().copy(
103+
104+
return defaultConfig().copy(
90105
storageDirPath = dirPath,
91106
network = Env.network,
92107
trustedPeers0conf = trustedPeerNodeIds,
@@ -95,46 +110,52 @@ class LightningService @Inject constructor(
95110
perChannelReserveSats = 1u,
96111
),
97112
)
113+
}
114+
115+
private suspend fun build(
116+
walletIndex: Int,
117+
customServerUrl: String?,
118+
customRgsServerUrl: String?,
119+
config: Config,
120+
): Node = ServiceQueue.LDK.background {
121+
val nodeEntropy = NodeEntropy.fromBip39Mnemonic(
122+
mnemonic = keychain.loadString(Keychain.Key.BIP39_MNEMONIC.name) ?: throw ServiceError.MnemonicNotFound,
123+
passphrase = keychain.loadString(Keychain.Key.BIP39_PASSPHRASE.name),
124+
)
98125

99126
val builder = Builder.fromConfig(config).apply {
100127
setCustomLogger(LdkLogWriter())
101-
102128
configureChainSource(customServerUrl)
103129
configureGossipSource(customRgsServerUrl)
104-
105-
setEntropyBip39Mnemonic(mnemonic, passphrase)
106130
}
107-
108-
Logger.debug("Building node…")
109-
110-
val vssStoreId = vssStoreIdProvider.getVssStoreId(walletIndex)
111-
112-
ServiceQueue.LDK.background {
113-
node = try {
114-
val lnurlAuthServerUrl = Env.lnurlAuthServerUrl
115-
val vssUrl = Env.vssServerUrl
116-
Logger.verbose("Building ldk-node with vssUrl: '$vssUrl'")
117-
Logger.verbose("Building ldk-node with lnurlAuthServerUrl: '$lnurlAuthServerUrl'")
118-
if (lnurlAuthServerUrl.isNotEmpty()) {
119-
builder.buildWithVssStore(
120-
vssUrl = vssUrl,
121-
storeId = vssStoreId,
122-
lnurlAuthServerUrl = lnurlAuthServerUrl,
123-
fixedHeaders = emptyMap(),
124-
)
125-
} else {
126-
builder.buildWithVssStoreAndFixedHeaders(
127-
vssUrl = vssUrl,
128-
storeId = vssStoreId,
129-
fixedHeaders = emptyMap(),
130-
)
131-
}
132-
} catch (e: BuildException) {
133-
throw LdkError(e)
131+
try {
132+
val vssStoreId = vssStoreIdProvider.getVssStoreId(walletIndex)
133+
val lnurlAuthServerUrl = Env.lnurlAuthServerUrl
134+
val vssUrl = Env.vssServerUrl
135+
Logger.verbose("Building ldk-node with vssUrl: '$vssUrl'")
136+
Logger.verbose("Building ldk-node with lnurlAuthServerUrl: '$lnurlAuthServerUrl'")
137+
if (lnurlAuthServerUrl.isNotEmpty()) {
138+
builder.buildWithVssStore(
139+
vssUrl = vssUrl,
140+
storeId = vssStoreId,
141+
lnurlAuthServerUrl = lnurlAuthServerUrl,
142+
fixedHeaders = emptyMap(),
143+
nodeEntropy = nodeEntropy,
144+
)
145+
} else {
146+
builder.buildWithVssStoreAndFixedHeaders(
147+
vssUrl = vssUrl,
148+
storeId = vssStoreId,
149+
fixedHeaders = emptyMap(),
150+
nodeEntropy = nodeEntropy,
151+
)
134152
}
153+
} catch (e: BuildException) {
154+
throw LdkError(e)
155+
} finally {
156+
// cleanup sensitive data
157+
nodeEntropy.destroy()
135158
}
136-
137-
Logger.info("LDK node setup")
138159
}
139160

140161
private suspend fun Builder.configureGossipSource(customRgsServerUrl: String?) {

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import androidx.navigation.compose.composable
3636
import androidx.navigation.compose.currentBackStackEntryAsState
3737
import androidx.navigation.compose.rememberNavController
3838
import androidx.navigation.toRoute
39-
import dev.chrisbanes.haze.rememberHazeState
4039
import kotlinx.coroutines.delay
4140
import kotlinx.coroutines.launch
4241
import kotlinx.serialization.Serializable
@@ -349,9 +348,7 @@ fun ContentView(
349348

350349
val hasSeenWidgetsIntro by settingsViewModel.hasSeenWidgetsIntro.collectAsStateWithLifecycle()
351350
val hasSeenShopIntro by settingsViewModel.hasSeenShopIntro.collectAsStateWithLifecycle()
352-
353351
val currentSheet by appViewModel.currentSheet.collectAsStateWithLifecycle()
354-
val hazeState = rememberHazeState()
355352

356353
Box(
357354
modifier = modifier.fillMaxSize()

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

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import to.bitkit.ext.amountSats
4444
import to.bitkit.ext.balanceUiText
4545
import to.bitkit.ext.channelId
4646
import to.bitkit.ext.createChannelDetails
47-
import to.bitkit.ext.formatted
47+
import to.bitkit.ext.formatToString
4848
import to.bitkit.ext.uri
4949
import to.bitkit.models.NodeLifecycleState
5050
import to.bitkit.models.Toast
@@ -68,7 +68,6 @@ import to.bitkit.ui.theme.Colors
6868
import to.bitkit.ui.utils.copyToClipboard
6969
import to.bitkit.ui.utils.withAccent
7070
import to.bitkit.viewmodels.MainUiState
71-
import java.time.Instant
7271

7372
@Composable
7473
fun NodeInfoScreen(
@@ -194,30 +193,53 @@ private fun NodeStateSection(
194193
Column(modifier = Modifier.fillMaxWidth()) {
195194
SectionHeader("Node State")
196195
SettingsTextButtonRow(
197-
title = "Node State:",
196+
title = stringResource(R.string.lightning__status),
198197
value = nodeLifecycleState.uiText,
199198
)
200199

201200
nodeStatus?.let { status ->
202201
SettingsTextButtonRow(
203-
title = "Ready:",
202+
title = stringResource(R.string.common_ready),
204203
value = if (status.isRunning) "" else "",
205204
)
206205
SettingsTextButtonRow(
207-
title = "Lightning wallet sync time:",
206+
title = stringResource(R.string.lightning__block_height),
207+
value = "${status.currentBestBlock.height}",
208+
)
209+
SettingsTextButtonRow(
210+
title = stringResource(R.string.lightning__monitor_height),
211+
value = status.latestChannelMonitorArchivalHeight
212+
?.let { "$it" }
213+
?: stringResource(R.string.common__never),
214+
)
215+
SettingsTextButtonRow(
216+
title = stringResource(R.string.lightning__node_sync_time),
208217
value = status.latestLightningWalletSyncTimestamp
209-
?.let { Instant.ofEpochSecond(it.toLong()).formatted() }
210-
?: "Never",
218+
?.formatToString()
219+
?: stringResource(R.string.common__never),
211220
)
212221
SettingsTextButtonRow(
213-
title = "Onchain wallet sync time:",
222+
title = stringResource(R.string.lightning__onchain_sync_time),
214223
value = status.latestOnchainWalletSyncTimestamp
215-
?.let { Instant.ofEpochSecond(it.toLong()).formatted() }
216-
?: "Never",
224+
?.formatToString()
225+
?: stringResource(R.string.common__never),
217226
)
218227
SettingsTextButtonRow(
219-
title = "Block height:",
220-
value = "${status.currentBestBlock.height}",
228+
title = stringResource(R.string.lightning__fee_rate_update_time),
229+
value = status.latestFeeRateCacheUpdateTimestamp
230+
?.formatToString()
231+
?: stringResource(R.string.common__never),
232+
)
233+
SettingsTextButtonRow(
234+
title = stringResource(R.string.lightning__rgs_snapshot_time),
235+
value = status.latestRgsSnapshotTimestamp
236+
?.formatToString()
237+
?: stringResource(R.string.common__never),
238+
)
239+
SettingsTextButtonRow(
240+
title = stringResource(R.string.lightning__scores_sync_time),
241+
value = status.latestPathfindingScoresSyncTimestamp?.formatToString()
242+
?: stringResource(R.string.common__never),
221243
)
222244
}
223245
}
@@ -226,23 +248,23 @@ private fun NodeStateSection(
226248
@Composable
227249
private fun WalletBalancesSection(balanceDetails: BalanceDetails) {
228250
Column(modifier = Modifier.fillMaxWidth()) {
229-
SectionHeader("Wallet Balances")
251+
SectionHeader(stringResource(R.string.lightning__wallet_balances))
230252
Column {
231253
SettingsTextButtonRow(
232-
title = "Total onchain:",
254+
title = stringResource(R.string.lightning__total_onchain),
233255
value = "${balanceDetails.totalOnchainBalanceSats.formatToModernDisplay()}",
234256
)
235257
SettingsTextButtonRow(
236-
title = "Spendable onchain:",
258+
title = stringResource(R.string.lightning__spendable_onchain),
237259
value = "${balanceDetails.spendableOnchainBalanceSats.formatToModernDisplay()}",
238260
)
239261
SettingsTextButtonRow(
240-
title = "Total anchor channels reserve:",
241-
value = "${balanceDetails.totalAnchorChannelsReserveSats.formatToModernDisplay()}",
262+
title = stringResource(R.string.lightning__total_lightning),
263+
value = "${balanceDetails.totalLightningBalanceSats.formatToModernDisplay()}",
242264
)
243265
SettingsTextButtonRow(
244-
title = "Total lightning:",
245-
value = "${balanceDetails.totalLightningBalanceSats.formatToModernDisplay()}",
266+
title = stringResource(R.string.lightning__total_anchor_channels_reserve),
267+
value = "${balanceDetails.totalAnchorChannelsReserveSats.formatToModernDisplay()}",
246268
)
247269
}
248270
}
@@ -251,7 +273,7 @@ private fun WalletBalancesSection(balanceDetails: BalanceDetails) {
251273
@Composable
252274
private fun LightningBalancesSection(balances: List<LightningBalance>) {
253275
Column(modifier = Modifier.fillMaxWidth()) {
254-
SectionHeader("Lightning Balances")
276+
SectionHeader(stringResource(R.string.lightning__lightning_balances))
255277
balances.forEach { balance ->
256278
Column(
257279
modifier = Modifier.fillMaxWidth()
@@ -321,39 +343,39 @@ private fun ChannelsSection(
321343
VerticalSpacer(8.dp)
322344

323345
ChannelDetailRow(
324-
title = "Ready:",
346+
title = stringResource(R.string.common_ready),
325347
value = if (channel.isChannelReady) "" else "",
326348
)
327349
ChannelDetailRow(
328-
title = "Usable:",
350+
title = stringResource(R.string.common__usable),
329351
value = if (channel.isUsable) "" else "",
330352
)
331353
ChannelDetailRow(
332-
title = "Announced:",
354+
title = stringResource(R.string.common__announced),
333355
value = if (channel.isAnnounced) "🌐" else "🔒",
334356
)
335357
ChannelDetailRow(
336-
title = "Inbound capacity:",
358+
title = stringResource(R.string.lightning__inbound_capacity),
337359
value = "${(channel.inboundCapacityMsat / 1000u).formatToModernDisplay()}",
338360
)
339361
ChannelDetailRow(
340-
title = "Inbound htlc max:",
362+
title = stringResource(R.string.lightning__inbound_htlc_max),
341363
value = "${(channel.inboundHtlcMaximumMsat?.div(1000u) ?: 0u).formatToModernDisplay()}",
342364
)
343365
ChannelDetailRow(
344-
title = "Inbound htlc min:",
366+
title = stringResource(R.string.lightning__inbound_htlc_min),
345367
value = "${(channel.inboundHtlcMinimumMsat / 1000u).formatToModernDisplay()}",
346368
)
347369
ChannelDetailRow(
348-
title = "Next outbound htlc limit:",
370+
title = stringResource(R.string.lightning__next_outbound_htlc_limit),
349371
value = "${(channel.nextOutboundHtlcLimitMsat / 1000u).formatToModernDisplay()}",
350372
)
351373
ChannelDetailRow(
352-
title = "Next outbound htlc min:",
374+
title = stringResource(R.string.lightning__next_outbound_htlc_min),
353375
value = "${(channel.nextOutboundHtlcMinimumMsat / 1000u).formatToModernDisplay()}",
354376
)
355377
ChannelDetailRow(
356-
title = "Confirmations:",
378+
title = stringResource(R.string.common_confirmations),
357379
value = "${channel.confirmations ?: 0}/${channel.confirmationsRequired ?: 0}",
358380
)
359381

@@ -452,7 +474,6 @@ private fun PreviewDevMode() {
452474
nodeLifecycleState = NodeLifecycleState.Running,
453475
nodeStatus = NodeStatus(
454476
isRunning = true,
455-
isListening = true,
456477
currentBestBlock = BestBlock(
457478
height = 1000u,
458479
blockHash = "0123456789abcDef",
@@ -463,6 +484,7 @@ private fun PreviewDevMode() {
463484
latestRgsSnapshotTimestamp = null,
464485
latestNodeAnnouncementBroadcastTimestamp = null,
465486
latestChannelMonitorArchivalHeight = null,
487+
latestPathfindingScoresSyncTimestamp = null,
466488
),
467489
nodeId = "0348a2b7c2d3f4e5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9",
468490
peers = listOf(Env.Peers.staging),

app/src/main/java/to/bitkit/ui/components/TabBar.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ import to.bitkit.ui.shared.util.primaryButtonStyle
4646
import to.bitkit.ui.theme.AppThemeSurface
4747
import to.bitkit.ui.theme.Colors
4848

49-
5049
private val iconToTextGap = 4.dp
5150
private val iconSize = 20.dp
5251

0 commit comments

Comments
 (0)