Skip to content

Commit 20e25e9

Browse files
committed
Merge branch 'master' into feat/time-sheet-polish
# Conflicts: # app/src/main/java/to/bitkit/fcm/WakeNodeWorker.kt
2 parents 06d07d4 + 6d9b4ef commit 20e25e9

File tree

11 files changed

+93
-25
lines changed

11 files changed

+93
-25
lines changed

.github/workflows/e2e.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ jobs:
4646
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4747
CHATWOOT_API: ${{ secrets.CHATWOOT_API }}
4848
E2E: true
49+
GEO: false
4950
run: ./gradlew assembleDevDebug
5051

5152
- name: Rename APK

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ Simply pass `E2E=true` as environment variable and build any flavor.
7676
E2E=true ./gradlew assembleDevRelease
7777
```
7878

79+
#### Disable Geoblocking Checks
80+
81+
By default, geoblocking checks via API are enabled. To disable at build time, use the `GEO` environment variable:
82+
83+
```sh
84+
GEO=false E2E=true ./gradlew assembleDevRelease
85+
```
86+
7987
### Build for Release
8088

8189
**Prerequisites**

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ android {
4646
useSupportLibrary = true
4747
}
4848
buildConfigField("boolean", "E2E", System.getenv("E2E")?.toBoolean()?.toString() ?: "false")
49+
buildConfigField("boolean", "GEO", System.getenv("GEO")?.toBoolean()?.toString() ?: "true")
4950
}
5051

5152
flavorDimensions += "network"

app/src/androidTest/java/to/bitkit/services/BlocktankTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ class BlocktankTest {
8282
}
8383

8484
@Test
85-
fun testCreateCjitOrder() = runBlocking {
85+
fun testCreateCjitEntry() = runBlocking {
8686
// Test creating a CJIT order
8787
val channelSizeSat = 100_000uL // 100k sats
8888
val invoiceSat = 10_000uL // 10k sats for the invoice
89-
val invoiceDescription = "Test CJIT order"
89+
val invoiceDescription = "Test CJIT"
9090
val nodeId = "03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad" // Example node ID
9191
val channelExpiryWeeks = 6u
9292
val options = CreateCjitOptions(source = "bitkit", discountCode = null)
@@ -122,7 +122,7 @@ class BlocktankTest {
122122
)
123123

124124
// Test getting CJIT entries
125-
val entries = service.blocktank.cjitOrders(
125+
val entries = service.blocktank.cjitEntries(
126126
entryIds = listOf(cjitEntry.id),
127127
filter = null,
128128
refresh = true

app/src/main/java/to/bitkit/env/Env.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import kotlin.io.path.Path
1515
internal object Env {
1616
val isDebug = BuildConfig.DEBUG
1717
const val isE2eTest = BuildConfig.E2E
18+
const val isGeoblockingEnabled = BuildConfig.GEO
1819
val network = Network.valueOf(BuildConfig.NETWORK)
1920
val walletSyncIntervalSecs = 10_uL // TODO review
2021
val platform = "Android ${Build.VERSION.RELEASE} (API ${Build.VERSION.SDK_INT})"

app/src/main/java/to/bitkit/fcm/WakeNodeWorker.kt

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import to.bitkit.models.BlocktankNotificationType.wakeToTimeout
2828
import to.bitkit.models.NewTransactionSheetDetails
2929
import to.bitkit.models.NewTransactionSheetDirection
3030
import to.bitkit.models.NewTransactionSheetType
31+
import to.bitkit.repositories.ActivityRepo
32+
import to.bitkit.repositories.BlocktankRepo
3133
import to.bitkit.repositories.LightningRepo
3234
import to.bitkit.services.CoreService
3335
import to.bitkit.ui.pushNotification
@@ -41,6 +43,8 @@ class WakeNodeWorker @AssistedInject constructor(
4143
@Assisted private val workerParams: WorkerParameters,
4244
private val coreService: CoreService,
4345
private val lightningRepo: LightningRepo,
46+
private val blocktankRepo: BlocktankRepo,
47+
private val activityRepo: ActivityRepo,
4448
private val settingsStore: SettingsStore,
4549
) : CoroutineWorker(appContext, workerParams) {
4650
private val self = this
@@ -151,15 +155,21 @@ class WakeNodeWorker @AssistedInject constructor(
151155
val sats = channel.amountOnClose
152156
val content = if (showDetails) "$BITCOIN_SYMBOL $sats" else openBitkitMessage
153157
self.bestAttemptContent?.title = content
154-
// Save for UI to pick up
155-
NewTransactionSheetDetails.save(
156-
appContext,
157-
NewTransactionSheetDetails(
158-
type = NewTransactionSheetType.LIGHTNING,
159-
direction = NewTransactionSheetDirection.RECEIVED,
160-
sats = channel.amountOnClose.toLong(),
158+
val cjitEntry = channel.let { blocktankRepo.getCjitEntry(it) }
159+
if (cjitEntry != null) {
160+
val amount = channel.amountOnClose.toLong()
161+
162+
// Save for UI to pick up
163+
NewTransactionSheetDetails.save(
164+
appContext,
165+
NewTransactionSheetDetails(
166+
type = NewTransactionSheetType.LIGHTNING,
167+
direction = NewTransactionSheetDirection.RECEIVED,
168+
sats = sats,
169+
)
161170
)
162-
)
171+
activityRepo.insertActivityFromCjit(cjitEntry = cjitEntry, channel = channel)
172+
}
163173
}
164174
} else if (self.notificationType == orderPaymentConfirmed) {
165175
self.bestAttemptContent?.title = "Channel opened"

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package to.bitkit.repositories
33
import com.synonym.bitkitcore.Activity
44
import com.synonym.bitkitcore.Activity.Onchain
55
import com.synonym.bitkitcore.ActivityFilter
6+
import com.synonym.bitkitcore.IcJitEntry
7+
import com.synonym.bitkitcore.LightningActivity
8+
import com.synonym.bitkitcore.PaymentState
69
import com.synonym.bitkitcore.PaymentType
710
import com.synonym.bitkitcore.SortDirection
811
import kotlinx.coroutines.CoroutineDispatcher
@@ -14,6 +17,7 @@ import kotlinx.coroutines.flow.first
1417
import kotlinx.coroutines.flow.map
1518
import kotlinx.coroutines.withContext
1619
import kotlinx.coroutines.withTimeout
20+
import org.lightningdevkit.ldknode.ChannelDetails
1721
import org.lightningdevkit.ldknode.PaymentDetails
1822
import to.bitkit.data.AppDb
1923
import to.bitkit.data.CacheStore
@@ -22,6 +26,7 @@ import to.bitkit.data.dto.PendingBoostActivity
2226
import to.bitkit.data.dto.TransferType
2327
import to.bitkit.data.entities.TagMetadataEntity
2428
import to.bitkit.di.BgDispatcher
29+
import to.bitkit.ext.amountOnClose
2530
import to.bitkit.ext.matchesPaymentId
2631
import to.bitkit.ext.nowTimestamp
2732
import to.bitkit.ext.rawId
@@ -504,6 +509,41 @@ class ActivityRepo @Inject constructor(
504509
}
505510
}
506511

512+
/**
513+
* Inserts a new activity for a fulfilled (channel ready) cjit channel order
514+
*/
515+
suspend fun insertActivityFromCjit(
516+
cjitEntry: IcJitEntry?,
517+
channel: ChannelDetails,
518+
): Result<Unit> = withContext(bgDispatcher) {
519+
runCatching {
520+
requireNotNull(cjitEntry)
521+
522+
val amount = channel.amountOnClose
523+
val now = nowTimestamp().epochSecond.toULong()
524+
525+
return@withContext insertActivity(
526+
Activity.Lightning(
527+
LightningActivity(
528+
id = channel.fundingTxo?.txid.orEmpty(),
529+
txType = PaymentType.RECEIVED,
530+
status = PaymentState.SUCCEEDED,
531+
value = amount,
532+
fee = 0U,
533+
invoice = cjitEntry.invoice.request,
534+
message = "",
535+
timestamp = now,
536+
preimage = null,
537+
createdAt = now,
538+
updatedAt = null,
539+
)
540+
)
541+
)
542+
}.onFailure { e ->
543+
Logger.error("insertActivity error", e, context = TAG)
544+
}
545+
}
546+
507547
suspend fun addActivityToPendingBoost(pendingBoostActivity: PendingBoostActivity) = withContext(bgDispatcher) {
508548
cacheStore.addActivityToPendingBoost(pendingBoostActivity)
509549
}

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

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,11 @@ class BlocktankRepo @Inject constructor(
9797
}
9898
}
9999

100-
suspend fun isCjitOrder(channel: ChannelDetails): Boolean = withContext(bgDispatcher) {
101-
return@withContext runCatching {
102-
_blocktankState.value.cjitEntries.any { order ->
103-
order.channelSizeSat == channel.channelValueSats &&
104-
order.lspNode.pubkey == channel.counterpartyNodeId
105-
}
106-
}.getOrDefault(false)
100+
suspend fun getCjitEntry(channel: ChannelDetails): IcJitEntry? = withContext(bgDispatcher) {
101+
return@withContext _blocktankState.value.cjitEntries.firstOrNull { order ->
102+
order.channelSizeSat == channel.channelValueSats &&
103+
order.lspNode.pubkey == channel.counterpartyNodeId
104+
}
107105
}
108106

109107
suspend fun refreshInfo() = withContext(bgDispatcher) {
@@ -133,7 +131,7 @@ class BlocktankRepo @Inject constructor(
133131

134132
// Sync instantly from cache
135133
val cachedOrders = coreService.blocktank.orders(refresh = false)
136-
val cachedCjitEntries = coreService.blocktank.cjitOrders(refresh = false)
134+
val cachedCjitEntries = coreService.blocktank.cjitEntries(refresh = false)
137135
_blocktankState.update { state ->
138136
state.copy(
139137
orders = cachedOrders,
@@ -144,7 +142,7 @@ class BlocktankRepo @Inject constructor(
144142

145143
// Then refresh from server
146144
val orders = coreService.blocktank.orders(refresh = true)
147-
val cjitEntries = coreService.blocktank.cjitOrders(refresh = true)
145+
val cjitEntries = coreService.blocktank.cjitEntries(refresh = true)
148146
_blocktankState.update { state ->
149147
state.copy(
150148
orders = orders,

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,13 @@ class CoreService @Inject constructor(
111111
}
112112
}
113113

114+
@Suppress("KotlinConstantConditions")
114115
private suspend fun isGeoBlocked(): Boolean {
116+
if (!Env.isGeoblockingEnabled) {
117+
Logger.verbose("Geoblocking disabled via build config", context = "GeoCheck")
118+
return false
119+
}
120+
115121
return ServiceQueue.CORE.background {
116122
runCatching {
117123
Logger.verbose("Checking geo status…", context = "GeoCheck")
@@ -578,7 +584,7 @@ class BlocktankService(
578584
}
579585
}
580586

581-
suspend fun cjitOrders(
587+
suspend fun cjitEntries(
582588
entryIds: List<String>? = null,
583589
filter: CJitStateEnum? = null,
584590
refresh: Boolean = true,

app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,15 +217,18 @@ class AppViewModel @Inject constructor(
217217

218218
is Event.ChannelReady -> {
219219
val channel = lightningRepo.getChannels()?.find { it.channelId == event.channelId }
220-
if (channel != null && blocktankRepo.isCjitOrder(channel)) {
220+
val cjitEntry = channel?.let { blocktankRepo.getCjitEntry(it) }
221+
if (cjitEntry != null) {
222+
val amount = channel.amountOnClose.toLong()
221223
showNewTransactionSheet(
222224
NewTransactionSheetDetails(
223225
type = NewTransactionSheetType.LIGHTNING,
224226
direction = NewTransactionSheetDirection.RECEIVED,
225-
sats = channel.amountOnClose.toLong(),
227+
sats = amount,
226228
),
227229
event = event
228230
)
231+
activityRepo.insertActivityFromCjit(cjitEntry = cjitEntry, channel = channel)
229232
} else {
230233
toast(
231234
type = Toast.ToastType.LIGHTNING,

0 commit comments

Comments
 (0)