diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 9b954b9ce..6b9aa1fa7 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -46,6 +46,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} CHATWOOT_API: ${{ secrets.CHATWOOT_API }} E2E: true + GEO: false run: ./gradlew assembleDevDebug - name: Rename APK diff --git a/README.md b/README.md index 6dcf02b91..92c185cfc 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,14 @@ Simply pass `E2E=true` as environment variable and build any flavor. E2E=true ./gradlew assembleDevRelease ``` +#### Disable Geoblocking Checks + +By default, geoblocking checks via API are enabled. To disable at build time, use the `GEO` environment variable: + +```sh +GEO=false E2E=true ./gradlew assembleDevRelease +``` + ### Build for Release **Prerequisites** diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4c163bd2b..630f7eddb 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -46,6 +46,7 @@ android { useSupportLibrary = true } buildConfigField("boolean", "E2E", System.getenv("E2E")?.toBoolean()?.toString() ?: "false") + buildConfigField("boolean", "GEO", System.getenv("GEO")?.toBoolean()?.toString() ?: "true") } flavorDimensions += "network" diff --git a/app/src/androidTest/java/to/bitkit/services/BlocktankTest.kt b/app/src/androidTest/java/to/bitkit/services/BlocktankTest.kt index 7be51306c..dafbce5e2 100644 --- a/app/src/androidTest/java/to/bitkit/services/BlocktankTest.kt +++ b/app/src/androidTest/java/to/bitkit/services/BlocktankTest.kt @@ -82,11 +82,11 @@ class BlocktankTest { } @Test - fun testCreateCjitOrder() = runBlocking { + fun testCreateCjitEntry() = runBlocking { // Test creating a CJIT order val channelSizeSat = 100_000uL // 100k sats val invoiceSat = 10_000uL // 10k sats for the invoice - val invoiceDescription = "Test CJIT order" + val invoiceDescription = "Test CJIT" val nodeId = "03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad" // Example node ID val channelExpiryWeeks = 6u val options = CreateCjitOptions(source = "bitkit", discountCode = null) @@ -122,7 +122,7 @@ class BlocktankTest { ) // Test getting CJIT entries - val entries = service.blocktank.cjitOrders( + val entries = service.blocktank.cjitEntries( entryIds = listOf(cjitEntry.id), filter = null, refresh = true diff --git a/app/src/main/java/to/bitkit/env/Env.kt b/app/src/main/java/to/bitkit/env/Env.kt index 0bee8bca4..dd8d6ff8c 100644 --- a/app/src/main/java/to/bitkit/env/Env.kt +++ b/app/src/main/java/to/bitkit/env/Env.kt @@ -15,6 +15,7 @@ import kotlin.io.path.Path internal object Env { val isDebug = BuildConfig.DEBUG const val isE2eTest = BuildConfig.E2E + const val isGeoblockingEnabled = BuildConfig.GEO val network = Network.valueOf(BuildConfig.NETWORK) val walletSyncIntervalSecs = 10_uL // TODO review val platform = "Android ${Build.VERSION.RELEASE} (API ${Build.VERSION.SDK_INT})" diff --git a/app/src/main/java/to/bitkit/fcm/WakeNodeWorker.kt b/app/src/main/java/to/bitkit/fcm/WakeNodeWorker.kt index 8a281e6b7..d318114e4 100644 --- a/app/src/main/java/to/bitkit/fcm/WakeNodeWorker.kt +++ b/app/src/main/java/to/bitkit/fcm/WakeNodeWorker.kt @@ -148,8 +148,8 @@ class WakeNodeWorker @AssistedInject constructor( val sats = channel.amountOnClose self.bestAttemptContent?.title = "Received ⚡ $sats sats" - val cjitOrder = channel.let { blocktankRepo.getCjitOrder(it) } - if (cjitOrder != null) { + val cjitEntry = channel.let { blocktankRepo.getCjitEntry(it) } + if (cjitEntry != null) { val amount = channel.amountOnClose.toLong() // Save for UI to pick up @@ -161,7 +161,7 @@ class WakeNodeWorker @AssistedInject constructor( sats = amount, ) ) - activityRepo.insertActivityFromChannel(cjitOrder = cjitOrder, channel = channel) + activityRepo.insertActivityFromCjit(cjitEntry = cjitEntry, channel = channel) } } } else if (self.notificationType == orderPaymentConfirmed) { diff --git a/app/src/main/java/to/bitkit/repositories/ActivityRepo.kt b/app/src/main/java/to/bitkit/repositories/ActivityRepo.kt index eea44e120..b57a733af 100644 --- a/app/src/main/java/to/bitkit/repositories/ActivityRepo.kt +++ b/app/src/main/java/to/bitkit/repositories/ActivityRepo.kt @@ -510,17 +510,17 @@ class ActivityRepo @Inject constructor( } /** - * Inserts a new activity + * Inserts a new activity for a fulfilled (channel ready) cjit channel order */ - suspend fun insertActivityFromChannel( - cjitOrder: IcJitEntry?, + suspend fun insertActivityFromCjit( + cjitEntry: IcJitEntry?, channel: ChannelDetails, ): Result = withContext(bgDispatcher) { runCatching { - requireNotNull(cjitOrder) + requireNotNull(cjitEntry) val amount = channel.amountOnClose - val now = nowTimestamp().toEpochMilli().toULong() + val now = nowTimestamp().epochSecond.toULong() return@withContext insertActivity( Activity.Lightning( @@ -530,7 +530,7 @@ class ActivityRepo @Inject constructor( status = PaymentState.SUCCEEDED, value = amount, fee = 0U, - invoice = cjitOrder.invoice.request, + invoice = cjitEntry.invoice.request, message = "", timestamp = now, preimage = null, diff --git a/app/src/main/java/to/bitkit/repositories/BlocktankRepo.kt b/app/src/main/java/to/bitkit/repositories/BlocktankRepo.kt index f485dce01..88e4f26b6 100644 --- a/app/src/main/java/to/bitkit/repositories/BlocktankRepo.kt +++ b/app/src/main/java/to/bitkit/repositories/BlocktankRepo.kt @@ -97,7 +97,7 @@ class BlocktankRepo @Inject constructor( } } - suspend fun getCjitOrder(channel: ChannelDetails): IcJitEntry? = withContext(bgDispatcher) { + suspend fun getCjitEntry(channel: ChannelDetails): IcJitEntry? = withContext(bgDispatcher) { return@withContext _blocktankState.value.cjitEntries.firstOrNull { order -> order.channelSizeSat == channel.channelValueSats && order.lspNode.pubkey == channel.counterpartyNodeId @@ -131,7 +131,7 @@ class BlocktankRepo @Inject constructor( // Sync instantly from cache val cachedOrders = coreService.blocktank.orders(refresh = false) - val cachedCjitEntries = coreService.blocktank.cjitOrders(refresh = false) + val cachedCjitEntries = coreService.blocktank.cjitEntries(refresh = false) _blocktankState.update { state -> state.copy( orders = cachedOrders, @@ -142,7 +142,7 @@ class BlocktankRepo @Inject constructor( // Then refresh from server val orders = coreService.blocktank.orders(refresh = true) - val cjitEntries = coreService.blocktank.cjitOrders(refresh = true) + val cjitEntries = coreService.blocktank.cjitEntries(refresh = true) _blocktankState.update { state -> state.copy( orders = orders, diff --git a/app/src/main/java/to/bitkit/services/CoreService.kt b/app/src/main/java/to/bitkit/services/CoreService.kt index 4c2cd32fb..0b1823e1f 100644 --- a/app/src/main/java/to/bitkit/services/CoreService.kt +++ b/app/src/main/java/to/bitkit/services/CoreService.kt @@ -111,7 +111,13 @@ class CoreService @Inject constructor( } } + @Suppress("KotlinConstantConditions") private suspend fun isGeoBlocked(): Boolean { + if (!Env.isGeoblockingEnabled) { + Logger.verbose("Geoblocking disabled via build config", context = "GeoCheck") + return false + } + return ServiceQueue.CORE.background { runCatching { Logger.verbose("Checking geo status…", context = "GeoCheck") @@ -578,7 +584,7 @@ class BlocktankService( } } - suspend fun cjitOrders( + suspend fun cjitEntries( entryIds: List? = null, filter: CJitStateEnum? = null, refresh: Boolean = true, diff --git a/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt b/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt index 06e5d79bb..54303e446 100644 --- a/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt +++ b/app/src/main/java/to/bitkit/viewmodels/AppViewModel.kt @@ -221,8 +221,8 @@ class AppViewModel @Inject constructor( is Event.ChannelReady -> { val channel = lightningRepo.getChannels()?.find { it.channelId == event.channelId } - val cjitOrder = channel?.let { blocktankRepo.getCjitOrder(it) } - if (cjitOrder != null) { + val cjitEntry = channel?.let { blocktankRepo.getCjitEntry(it) } + if (cjitEntry != null) { val amount = channel.amountOnClose.toLong() showNewTransactionSheet( NewTransactionSheetDetails( @@ -232,7 +232,7 @@ class AppViewModel @Inject constructor( ), event = event ) - activityRepo.insertActivityFromChannel(cjitOrder = cjitOrder, channel = channel) + activityRepo.insertActivityFromCjit(cjitEntry = cjitEntry, channel = channel) } else { toast( type = Toast.ToastType.LIGHTNING, diff --git a/app/src/test/java/to/bitkit/repositories/BlocktankRepoTest.kt b/app/src/test/java/to/bitkit/repositories/BlocktankRepoTest.kt index 63e04be70..18a423066 100644 --- a/app/src/test/java/to/bitkit/repositories/BlocktankRepoTest.kt +++ b/app/src/test/java/to/bitkit/repositories/BlocktankRepoTest.kt @@ -44,8 +44,8 @@ class BlocktankRepoTest : BaseUnitTest() { wheneverBlocking { coreService.blocktank.orders(refresh = false) }.thenReturn(emptyList()) wheneverBlocking { coreService.blocktank.orders(refresh = true) }.thenReturn(emptyList()) - wheneverBlocking { coreService.blocktank.cjitOrders(refresh = false) }.thenReturn(emptyList()) - wheneverBlocking { coreService.blocktank.cjitOrders(refresh = true) }.thenReturn(emptyList()) + wheneverBlocking { coreService.blocktank.cjitEntries(refresh = false) }.thenReturn(emptyList()) + wheneverBlocking { coreService.blocktank.cjitEntries(refresh = true) }.thenReturn(emptyList()) } private fun createSut(): BlocktankRepo {