Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ android {
applicationId = "to.bitkit"
minSdk = 28
targetSdk = 36
versionCode = 17
versionCode = 160
Comment thread
ben-kaufman marked this conversation as resolved.
Outdated
Comment thread
jvsena42 marked this conversation as resolved.
Outdated
versionName = "0.0.17"
testInstrumentationRunner = "to.bitkit.test.HiltTestRunner"
vectorDrawables {
Expand Down
22 changes: 17 additions & 5 deletions app/src/main/java/to/bitkit/repositories/ActivityRepo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,14 @@ class ActivityRepo @Inject constructor(
/**
* Syncs `ldk-node` [PaymentDetails] list to `bitkit-core` [Activity] items.
*/
private suspend fun syncLdkNodePayments(payments: List<PaymentDetails>): Result<Unit> = runCatching {
val channelIdsByTxId = findChannelsForPayments(payments)
coreService.activity.syncLdkNodePaymentsToActivities(payments, channelIdsByTxId = channelIdsByTxId)
}.onFailure { e ->
Logger.error("Error syncing LDK payments:", e, context = TAG)
suspend fun syncLdkNodePayments(payments: List<PaymentDetails>): Result<Unit> = withContext(bgDispatcher) {
return@withContext runCatching {
val channelIdsByTxId = findChannelsForPayments(payments)
coreService.activity.syncLdkNodePaymentsToActivities(payments, channelIdsByTxId = channelIdsByTxId)
notifyActivitiesChanged()
}.onFailure { e ->
Logger.error("Error syncing LDK payments:", e, context = TAG)
}
}

private suspend fun findChannelsForPayments(
Expand Down Expand Up @@ -666,6 +669,15 @@ class ActivityRepo @Inject constructor(
}
}

suspend fun markAllUnseenActivitiesAsSeen(): Result<Unit> = withContext(bgDispatcher) {
return@withContext runCatching {
coreService.activity.markAllUnseenActivitiesAsSeen()
notifyActivitiesChanged()
}.onFailure { e ->
Logger.error("Failed to mark all activities as seen: $e", e, context = TAG)
}
}

// MARK: - Development/Testing Methods

/**
Expand Down
20 changes: 18 additions & 2 deletions app/src/main/java/to/bitkit/repositories/LightningRepo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,11 @@ class LightningRepo @Inject constructor(
walletIndex: Int,
customServerUrl: String? = null,
customRgsServerUrl: String? = null,
channelMigration: org.lightningdevkit.ldknode.ChannelDataMigration? = null,
Comment thread
jvsena42 marked this conversation as resolved.
Outdated
) = withContext(bgDispatcher) {
return@withContext try {
val trustedPeers = getTrustedPeersFromBlocktank()
lightningService.setup(walletIndex, customServerUrl, customRgsServerUrl, trustedPeers)
lightningService.setup(walletIndex, customServerUrl, customRgsServerUrl, trustedPeers, channelMigration)
Result.success(Unit)
} catch (e: Throwable) {
Logger.error("Node setup error", e, context = TAG)
Expand All @@ -196,6 +197,7 @@ class LightningRepo @Inject constructor(
customServerUrl: String? = null,
customRgsServerUrl: String? = null,
eventHandler: NodeEventHandler? = null,
channelMigration: org.lightningdevkit.ldknode.ChannelDataMigration? = null,
): Result<Unit> = withContext(bgDispatcher) {
if (_isRecoveryMode.value) {
return@withContext Result.failure(RecoveryModeException())
Expand All @@ -214,7 +216,7 @@ class LightningRepo @Inject constructor(

// Setup if needed
if (lightningService.node == null) {
val setupResult = setup(walletIndex, customServerUrl, customRgsServerUrl)
val setupResult = setup(walletIndex, customServerUrl, customRgsServerUrl, channelMigration)
if (setupResult.isFailure) {
_lightningState.update {
it.copy(
Expand Down Expand Up @@ -264,6 +266,7 @@ class LightningRepo @Inject constructor(
shouldRetry = false,
customServerUrl = customServerUrl,
customRgsServerUrl = customRgsServerUrl,
channelMigration = channelMigration,
)
} else {
Logger.error("Node start error", e, context = TAG)
Expand Down Expand Up @@ -311,6 +314,19 @@ class LightningRepo @Inject constructor(
}
}

suspend fun restart(): Result<Unit> = withContext(bgDispatcher) {
stop().onFailure {
Logger.error("Failed to stop node during restart", it, context = TAG)
return@withContext Result.failure(it)
}
delay(500)
start(shouldRetry = false).onFailure {
Logger.error("Failed to start node during restart", it, context = TAG)
return@withContext Result.failure(it)
}
Result.success(Unit)
}

suspend fun sync(): Result<Unit> = executeWhenNodeRunning("sync") {
// If sync is in progress, mark pending and skip
if (!syncMutex.tryLock()) {
Expand Down
29 changes: 29 additions & 0 deletions app/src/main/java/to/bitkit/services/CoreService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1112,6 +1112,35 @@ class ActivityService(
markActivityAsSeen(activity.id, seenAt)
}

suspend fun markAllUnseenActivitiesAsSeen() = ServiceQueue.CORE.background {
val timestamp = (System.currentTimeMillis() / 1000).toULong()
val activities = getActivities(
filter = ActivityFilter.ALL,
txType = null,
tags = null,
search = null,
minDate = null,
maxDate = null,
limit = null,
sortDirection = null,
)

for (activity in activities) {
val isSeen = when (activity) {
is Activity.Onchain -> activity.v1.seenAt != null
is Activity.Lightning -> activity.v1.seenAt != null
}

if (!isSeen) {
val activityId = when (activity) {
is Activity.Onchain -> activity.v1.id
is Activity.Lightning -> activity.v1.id
}
markActivityAsSeen(activityId, timestamp)
}
Comment thread
jvsena42 marked this conversation as resolved.
}
}

suspend fun getBoostTxDoesExist(boostTxIds: List<String>): Map<String, Boolean> {
return ServiceQueue.CORE.background {
val doesExistMap = mutableMapOf<String, Boolean>()
Expand Down
13 changes: 13 additions & 0 deletions app/src/main/java/to/bitkit/services/LightningService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import org.lightningdevkit.ldknode.Bolt11InvoiceDescription
import org.lightningdevkit.ldknode.BuildException
import org.lightningdevkit.ldknode.Builder
import org.lightningdevkit.ldknode.ChannelConfig
import org.lightningdevkit.ldknode.ChannelDataMigration
import org.lightningdevkit.ldknode.ChannelDetails
import org.lightningdevkit.ldknode.CoinSelectionAlgorithm
import org.lightningdevkit.ldknode.Config
Expand Down Expand Up @@ -79,6 +80,7 @@ class LightningService @Inject constructor(
customServerUrl: String? = null,
customRgsServerUrl: String? = null,
trustedPeers: List<PeerDetails>? = null,
channelMigration: ChannelDataMigration? = null,
) {
Logger.debug("Building node…")

Expand All @@ -88,6 +90,7 @@ class LightningService @Inject constructor(
customServerUrl,
customRgsServerUrl,
config,
channelMigration,
)

Logger.info("LDK node setup")
Expand Down Expand Up @@ -123,11 +126,21 @@ class LightningService @Inject constructor(
customServerUrl: String?,
customRgsServerUrl: String?,
config: Config,
channelMigration: ChannelDataMigration? = null,
): Node = ServiceQueue.LDK.background {
val builder = Builder.fromConfig(config).apply {
setCustomLogger(LdkLogWriter())
configureChainSource(customServerUrl)
configureGossipSource(customRgsServerUrl)

if (channelMigration != null) {
setChannelDataMigration(channelMigration)
Logger.info(
"Applied channel migration: ${channelMigration.channelMonitors.size} monitors",
context = "Migration"
)
}

setEntropyBip39Mnemonic(
mnemonic = keychain.loadString(Keychain.Key.BIP39_MNEMONIC.name) ?: throw ServiceError.MnemonicNotFound,
passphrase = keychain.loadString(Keychain.Key.BIP39_PASSPHRASE.name),
Expand Down
Loading
Loading