Skip to content

Commit 70bde1a

Browse files
committed
fix: skip quickpay for contacts
1 parent 25b823b commit 70bde1a

2 files changed

Lines changed: 62 additions & 0 deletions

File tree

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,6 +1471,10 @@ class AppViewModel @Inject constructor(
14711471
}
14721472
}
14731473

1474+
private fun hasActiveContactPaymentContext() = synchronized(contactPaymentContextLock) {
1475+
activeContactPaymentContext != null
1476+
}
1477+
14741478
@Suppress("LongMethod", "CyclomaticComplexMethod", "ReturnCount")
14751479
private suspend fun onScanOnchain(invoice: OnChainInvoice, scanResult: String) {
14761480
val validatedAddress = runCatching { validateBitcoinAddress(invoice.address) }
@@ -1805,6 +1809,8 @@ class AppViewModel @Inject constructor(
18051809
lnurlPay: LnurlPayData? = null,
18061810
invoice: LightningInvoice? = null,
18071811
): Boolean {
1812+
if (hasActiveContactPaymentContext()) return false
1813+
18081814
val settings = settingsStore.data.first()
18091815
if (!settings.isQuickPayEnabled || amountSats == 0uL) {
18101816
return false

app/src/test/java/to/bitkit/viewmodels/AppViewModelSendFlowTest.kt

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package to.bitkit.viewmodels
22

33
import android.content.Context
4+
import com.synonym.bitkitcore.LightningInvoice
5+
import com.synonym.bitkitcore.NetworkType
6+
import com.synonym.bitkitcore.Scanner
47
import kotlinx.collections.immutable.persistentListOf
58
import kotlinx.coroutines.ExperimentalCoroutinesApi
69
import kotlinx.coroutines.flow.MutableSharedFlow
@@ -27,6 +30,7 @@ import to.bitkit.models.TransactionSpeed
2730
import to.bitkit.repositories.ActivityRepo
2831
import to.bitkit.repositories.BackupRepo
2932
import to.bitkit.repositories.BlocktankRepo
33+
import to.bitkit.repositories.BlocktankState
3034
import to.bitkit.repositories.ConnectivityRepo
3135
import to.bitkit.repositories.ConnectivityState
3236
import to.bitkit.repositories.CurrencyRepo
@@ -46,7 +50,9 @@ import to.bitkit.services.AppUpdaterService
4650
import to.bitkit.services.CoreService
4751
import to.bitkit.services.MigrationService
4852
import to.bitkit.test.BaseUnitTest
53+
import to.bitkit.ui.components.Sheet
4954
import to.bitkit.ui.shared.toast.ToastQueueManager
55+
import to.bitkit.ui.sheets.SendRoute
5056
import to.bitkit.usecases.FormatMoneyValue
5157
import to.bitkit.utils.timedsheets.TimedSheetManager
5258
import kotlin.test.assertEquals
@@ -108,6 +114,8 @@ class AppViewModelSendFlowTest : BaseUnitTest() {
108114
whenever(settingsStore.data).thenReturn(settingsData)
109115
whenever(cacheStore.data).thenReturn(flowOf(AppCacheData()))
110116
whenever(transferRepo.activeTransfers).thenReturn(flowOf(emptyList()))
117+
whenever(blocktankRepo.blocktankState).thenReturn(MutableStateFlow(BlocktankState()))
118+
whenever { blocktankRepo.refreshInfo() }.thenReturn(Result.success(Unit))
111119
whenever(timedSheetManager.currentSheet).thenReturn(MutableStateFlow(null))
112120
whenever(migrationService.isShowingMigrationLoading).thenReturn(MutableStateFlow(false))
113121
whenever { migrationService.needsPostMigrationSync() }.thenReturn(false)
@@ -313,6 +321,32 @@ class AppViewModelSendFlowTest : BaseUnitTest() {
313321
assertNull(pendingContactPaymentContext(paymentHash))
314322
}
315323

324+
@Test
325+
fun `lightning scan uses QuickPay when enabled`() = test {
326+
val bolt11 = "lnbcrt1quickpay"
327+
enableQuickPay(thresholdSats = 1000u)
328+
stubLightningScan(bolt11 = bolt11, amountSats = 500u)
329+
330+
sut.onScanResult(bolt11)
331+
advanceUntilIdle()
332+
333+
assertEquals(QuickPayData.Bolt11(sats = 500u, bolt11 = bolt11), sut.quickPayData.value)
334+
assertEquals(Sheet.Send(SendRoute.QuickPay), sut.currentSheet.value)
335+
}
336+
337+
@Test
338+
fun `contact lightning payment skips QuickPay and opens confirm`() = test {
339+
val bolt11 = "lnbcrt1contact"
340+
enableQuickPay(thresholdSats = 1000u)
341+
stubLightningScan(bolt11 = bolt11, amountSats = 500u)
342+
343+
sut.openContactPayment(paymentRequest = bolt11, publicKey = "pubkycontact")
344+
advanceUntilIdle()
345+
346+
assertNull(sut.quickPayData.value)
347+
assertEquals(Sheet.Send(SendRoute.Confirm), sut.currentSheet.value)
348+
}
349+
316350
@Test
317351
fun `channel ready refreshes public Paykit endpoints when sharing enabled`() = test {
318352
enablePublicPaykitSharing()
@@ -404,6 +438,28 @@ class AppViewModelSendFlowTest : BaseUnitTest() {
404438
assertEquals(0L, sut.sendUiState.value.lastLightningFee)
405439
}
406440

441+
private fun enableQuickPay(thresholdSats: ULong) {
442+
settingsData.value = SettingsData(isQuickPayEnabled = true, quickPayAmount = 5)
443+
whenever(currencyRepo.convertFiatToSats(5.0, "USD")).thenReturn(Result.success(thresholdSats))
444+
}
445+
446+
private suspend fun stubLightningScan(bolt11: String, amountSats: ULong) {
447+
whenever(coreService.decode(bolt11)).thenReturn(Scanner.Lightning(lightningInvoice(bolt11, amountSats)))
448+
whenever(lightningRepo.canSend(amountSats)).thenReturn(true)
449+
}
450+
451+
private fun lightningInvoice(bolt11: String, amountSats: ULong) = LightningInvoice(
452+
bolt11 = bolt11,
453+
paymentHash = byteArrayOf(1, 2, 3),
454+
amountSatoshis = amountSats,
455+
timestampSeconds = 0u,
456+
expirySeconds = 86_400u,
457+
isExpired = false,
458+
description = "",
459+
networkType = NetworkType.REGTEST,
460+
payeeNodeId = null,
461+
)
462+
407463
private suspend fun enablePublicPaykitSharing() {
408464
settingsData.value = SettingsData(sharesPublicPaykitEndpoints = true)
409465
walletState.value = WalletState(onchainAddress = "bc1qtest")

0 commit comments

Comments
 (0)