Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
3b45a24
feat: add pending suggestion types
jvsena42 Aug 14, 2025
ce5b469
feat: handle pending suggestion types WIP
jvsena42 Aug 14, 2025
112a2eb
chore: lint
jvsena42 Aug 14, 2025
d9d6ba8
chore: lint
jvsena42 Aug 14, 2025
594157d
chore: lint
jvsena42 Aug 14, 2025
22d46da
feat: in progress transfer cache logic
jvsena42 Aug 14, 2025
c68e983
feat: in progress transfer cache logic
jvsena42 Aug 14, 2025
10dc3fd
feat: cache in progress transfers
jvsena42 Aug 14, 2025
d8928cd
feat: cache in progress transfers
jvsena42 Aug 14, 2025
c2b9ce3
feat: update in progress transfers
jvsena42 Aug 14, 2025
2727791
feat: collect TO_SPENDING event
jvsena42 Aug 14, 2025
b3766ad
Merge branch 'master' into feat/card-pending-transactions
jvsena42 Aug 14, 2025
7066512
feat: collect transfer events and update suggestion list
jvsena42 Aug 15, 2025
a60e6d7
Merge branch 'master' into feat/card-pending-transactions
jvsena42 Aug 15, 2025
f66bbef
feat: add duration
jvsena42 Aug 15, 2025
c3763db
refactor: bg color
jvsena42 Aug 15, 2025
d233497
feat: glow effect
jvsena42 Aug 15, 2025
a9bd3cc
refactor: dismissable parameter
jvsena42 Aug 15, 2025
d857fa0
feat: handle duration
jvsena42 Aug 15, 2025
9bd0445
refactor: simplify glow effect
jvsena42 Aug 17, 2025
0207706
refactor: rename gradient modifier
jvsena42 Aug 17, 2025
7822bf2
feat: remove intermediary gradient colors
jvsena42 Aug 18, 2025
cd2273b
Merge branch 'master' into feat/card-pending-transactions
jvsena42 Aug 18, 2025
0c669fd
feat: radial card border
jvsena42 Aug 18, 2025
389100e
feat: disable glow
jvsena42 Aug 18, 2025
db6e253
feat: update shop card colors
jvsena42 Aug 18, 2025
1bbfd18
feat: animation time
jvsena42 Aug 18, 2025
eb410c0
feat: card gradient colors
jvsena42 Aug 18, 2025
5686b7e
chore: add todo
jvsena42 Aug 18, 2025
096f18d
feat: display LIGHTNING_READY card
jvsena42 Aug 18, 2025
d4a02a0
fix: existing item validation
jvsena42 Aug 18, 2025
615377d
refactor: remove duration
jvsena42 Aug 18, 2025
4ff454f
chore: remove logs
jvsena42 Aug 18, 2025
399b58d
chore: remove comment
jvsena42 Aug 18, 2025
3179d5d
chore: add TODO
jvsena42 Aug 18, 2025
d98cd54
chore: remove comment
jvsena42 Aug 18, 2025
5d6f680
chore: lint
jvsena42 Aug 18, 2025
756b8ed
chore: lint
jvsena42 Aug 18, 2025
876e050
chore: comment
jvsena42 Aug 18, 2025
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
18 changes: 18 additions & 0 deletions app/src/main/java/to/bitkit/data/CacheStore.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.serialization.Serializable
import to.bitkit.data.dto.InProgressTransfer
import to.bitkit.data.dto.PendingBoostActivity
import to.bitkit.data.dto.TransactionMetadata
import to.bitkit.data.serializers.AppCacheSerializer
Expand Down Expand Up @@ -130,6 +131,22 @@ class CacheStore @Inject constructor(
}
}

suspend fun addInProgressTransfer(item: InProgressTransfer) {
if (item in store.data.first().inProgressTransfers) return

store.updateData {
it.copy(inProgressTransfers = it.inProgressTransfers + item)
}
}

suspend fun removeInProgressTransfer(item: InProgressTransfer) {
if (item in store.data.first().inProgressTransfers) return

store.updateData {
it.copy(inProgressTransfers = it.inProgressTransfers - item)
}
}

suspend fun reset() {
store.updateData { AppCacheData() }
Logger.info("Deleted all app cached data.")
Expand All @@ -153,4 +170,5 @@ data class AppCacheData(
val activitiesPendingDelete: List<String> = listOf(),
val pendingBoostActivities: List<PendingBoostActivity> = listOf(),
val transactionsMetadata: List<TransactionMetadata> = listOf(),
val inProgressTransfers: List<InProgressTransfer> = listOf(),
)
9 changes: 9 additions & 0 deletions app/src/main/java/to/bitkit/data/dto/InProgressTransfer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package to.bitkit.data.dto

import kotlinx.serialization.Serializable

@Serializable
data class InProgressTransfer(
val activityId: String,
val type: TransferType,
)
8 changes: 8 additions & 0 deletions app/src/main/java/to/bitkit/data/dto/TransferType.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package to.bitkit.data.dto

enum class TransferType {
TO_SPENDING,
TO_SAVINGS,
FORCE_CLOSE,
COOP_CLOSE,
}
34 changes: 32 additions & 2 deletions app/src/main/java/to/bitkit/models/Suggestion.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ enum class Suggestion(
@StringRes val title: Int,
@StringRes val description: Int,
@DrawableRes val icon: Int,
val color: Color
val color: Color,
) {
BUY(
title = R.string.cards__buyBitcoin__title,
description = R.string.cards__buyBitcoin__description,
color = Colors.Brand,
icon = R.drawable.b_emboss
),
SPEND(
SPEND( // Lightning ready from RN
title = R.string.cards__lightning__title,
description = R.string.cards__lightning__description,
color = Colors.Purple,
Expand Down Expand Up @@ -66,6 +66,36 @@ enum class Suggestion(
color = Colors.Green,
icon = R.drawable.fast_forward
),

/**Replaces SPEND when a LN channel is being force closed*/
TRANSFER_PENDING(
title = R.string.cards__lightningSettingUp__title,
description = R.string.cards__transferPending__description,
color = Colors.Purple24,
icon = R.drawable.transfer
),

/**When the LN channel could not be cooped closed immediately*/
TRANSFER_CLOSING_CHANNEL(
title = R.string.cards__transferClosingChannel__title,
description = R.string.cards__transferClosingChannel__description,
color = Colors.Red24,
icon = R.drawable.transfer
),

/**Replaces SPEND when the transfer to spending balance is in progress*/
LIGHTNING_SETTING_UP(
title = R.string.cards__lightningSettingUp__title,
description = R.string.cards__lightningSettingUp__description,
color = Colors.Purple24,
icon = R.drawable.transfer
),
LIGHTNING_READY(
title = R.string.cards__lightningReady__title,
description = R.string.cards__lightningReady__description,
color = Colors.Purple24,
icon = R.drawable.transfer
),
}

fun String.toSuggestionOrNull() = Suggestion.entries.firstOrNull { it.name == this }
48 changes: 41 additions & 7 deletions app/src/main/java/to/bitkit/repositories/ActivityRepo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@
import com.synonym.bitkitcore.SortDirection
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.withContext
import org.lightningdevkit.ldknode.PaymentDetails
import to.bitkit.data.CacheStore
import to.bitkit.data.dto.InProgressTransfer
import to.bitkit.data.dto.PendingBoostActivity
import to.bitkit.data.dto.TransferType
import to.bitkit.di.BgDispatcher
import to.bitkit.ext.matchesPaymentId
import to.bitkit.ext.rawId
Expand All @@ -31,6 +36,9 @@

var isSyncingLdkNodePayments = false

private val _pendingTransfers: MutableStateFlow<List<Activity.Onchain>> = MutableStateFlow(emptyList())
val pendingTransfers = _pendingTransfers.asStateFlow()

suspend fun syncActivities(): Result<Unit> = withContext(bgDispatcher) {
Logger.debug("syncActivities called", context = TAG)

Expand All @@ -49,6 +57,7 @@
syncLdkNodePayments(payments = payments)
updateActivitiesMetadata()
boostPendingActivities()
updateInProgressTransfers()
isSyncingLdkNodePayments = false
return@withContext Result.success(Unit)
}.onFailure { e ->
Expand Down Expand Up @@ -278,20 +287,33 @@

when (activityToUpdate) {
is Activity.Onchain -> {
val onChainActivity = activityToUpdate.v1.copy(
feeRate = activityMetaData.feeRate.toULong(),
address = activityMetaData.address,
isTransfer = activityMetaData.isTransfer,
channelId = activityMetaData.channelId,
transferTxId = activityMetaData.transferTxId
)
val updatedActivity = Onchain(
v1 = activityToUpdate.v1.copy(
feeRate = activityMetaData.feeRate.toULong(),
address = activityMetaData.address,
isTransfer = activityMetaData.isTransfer,
channelId = activityMetaData.channelId,
transferTxId = activityMetaData.transferTxId
)
v1 = onChainActivity
)

updateActivity(
id = updatedActivity.v1.id,
activity = updatedActivity
).onSuccess {
if (onChainActivity.isTransfer && onChainActivity.doesExist) {
cacheStore.addInProgressTransfer(
InProgressTransfer(
activityId = updatedActivity.v1.id,
type = if (onChainActivity.txType == PaymentType.SENT) {
TransferType.TO_SPENDING
} else {
TransferType.TO_SAVINGS
}
)
)
}
cacheStore.removeTransactionMetadata(activityMetaData)
}
}
Expand All @@ -302,6 +324,18 @@
}
}

private suspend fun updateInProgressTransfers() {
cacheStore.data.first().inProgressTransfers.forEach { transfer ->
getActivity(transfer.activityId).onSuccess { activity ->
(activity as? Onchain)?.let { onChain ->
if (onChain.v1.confirmed) {
cacheStore.removeInProgressTransfer(transfer)
}
}
}
}
}

private suspend fun boostPendingActivities() = withContext(bgDispatcher) {
cacheStore.data.first().pendingBoostActivities.forEach { pendingBoostActivity ->
findActivityByPaymentId(
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/to/bitkit/ui/screens/wallets/HomeScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,11 @@ fun HomeScreen(
rootNavController.navigate(Routes.QuickPaySettings)
}
}

Suggestion.TRANSFER_PENDING -> Unit
Suggestion.TRANSFER_CLOSING_CHANNEL -> Unit
Suggestion.LIGHTNING_SETTING_UP -> TODO()
Suggestion.LIGHTNING_READY -> TODO()
}
},
onClickAddWidget = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import to.bitkit.models.widget.ArticleModel
import to.bitkit.models.widget.toArticleModel
import to.bitkit.models.widget.toBlockModel
import to.bitkit.repositories.ActivityRepo
import to.bitkit.repositories.CurrencyRepo
import to.bitkit.repositories.WalletRepo
import to.bitkit.repositories.WidgetsRepo
Expand All @@ -33,7 +34,8 @@
private val walletRepo: WalletRepo,
private val widgetsRepo: WidgetsRepo,
private val settingsStore: SettingsStore,
private val currencyRepo: CurrencyRepo
private val currencyRepo: CurrencyRepo,
private val activityRepo: ActivityRepo,
) : ViewModel() {

private val _uiState = MutableStateFlow(HomeUiState())
Expand Down Expand Up @@ -273,7 +275,7 @@
balanceState.totalOnchainSats > 0uL -> { // Only on chain balance
listOfNotNull(
Suggestion.BACK_UP.takeIf { !settings.backupVerified },
Suggestion.SPEND,
Suggestion.SPEND, // TODO Replace with LIGHTNING_SETTING_UP when the spending balance is confirming
Suggestion.SECURE.takeIf { !settings.isPinEnabled },
Suggestion.BUY,
Suggestion.SUPPORT,
Expand Down