@@ -3,35 +3,29 @@ package to.bitkit.ui.sheets
33import androidx.lifecycle.ViewModel
44import androidx.lifecycle.viewModelScope
55import com.synonym.bitkitcore.Activity
6+ import com.synonym.bitkitcore.PaymentState
67import com.synonym.bitkitcore.PaymentType
7- import com.synonym.bitkitcore.giftOrder
8- import com.synonym.bitkitcore.giftPay
98import dagger.hilt.android.lifecycle.HiltViewModel
109import kotlinx.coroutines.CoroutineDispatcher
11- import kotlinx.coroutines.delay
1210import kotlinx.coroutines.flow.MutableSharedFlow
1311import kotlinx.coroutines.flow.asSharedFlow
1412import kotlinx.coroutines.launch
1513import kotlinx.coroutines.withContext
16- import to.bitkit.async.ServiceQueue
1714import to.bitkit.di.BgDispatcher
18- import to.bitkit.ext.calculateRemoteBalance
15+ import to.bitkit.ext.nowTimestamp
1916import to.bitkit.models.NewTransactionSheetDetails
2017import to.bitkit.models.NewTransactionSheetDirection
2118import to.bitkit.models.NewTransactionSheetType
2219import to.bitkit.repositories.ActivityRepo
2320import to.bitkit.repositories.BlocktankRepo
24- import to.bitkit.repositories.LightningRepo
25- import to.bitkit.services.LightningService
21+ import to.bitkit.repositories.GiftClaimResult
2622import to.bitkit.utils.Logger
2723import javax.inject.Inject
2824import kotlin.time.Duration.Companion.milliseconds
2925
3026@HiltViewModel
3127class GiftViewModel @Inject constructor(
3228 @BgDispatcher private val bgDispatcher : CoroutineDispatcher ,
33- private val lightningRepo : LightningRepo ,
34- private val lightningService : LightningService ,
3529 private val blocktankRepo : BlocktankRepo ,
3630 private val activityRepo : ActivityRepo ,
3731) : ViewModel() {
@@ -65,98 +59,62 @@ class GiftViewModel @Inject constructor(
6559 }
6660 }
6761
68- @Suppress(" TooGenericExceptionCaught" )
6962 private suspend fun claimGift () = withContext(bgDispatcher) {
7063 if (isClaiming) return @withContext
7164 isClaiming = true
7265
7366 try {
74- lightningRepo.executeWhenNodeRunning(
75- operationName = " waitForNodeRunning" ,
67+ blocktankRepo.claimGiftCode(
68+ code = code,
69+ amount = amount,
7670 waitTimeout = NODE_STARTUP_TIMEOUT_MS .milliseconds,
77- ) {
78- Result .success(Unit )
79- }.getOrThrow()
80-
81- delay(PEER_CONNECTION_DELAY_MS )
82-
83- val channels = lightningRepo.lightningState.value.channels
84- val maxInboundCapacity = channels.calculateRemoteBalance()
85-
86- if (maxInboundCapacity >= amount) {
87- claimWithLiquidity()
88- } else {
89- claimWithoutLiquidity()
90- }
91- } catch (e: Exception ) {
92- handleGiftClaimError(e)
71+ ).fold(
72+ onSuccess = { result ->
73+ when (result) {
74+ is GiftClaimResult .SuccessWithLiquidity -> {
75+ _navigationEvent .emit(GiftRoute .Success )
76+ }
77+ is GiftClaimResult .SuccessWithoutLiquidity -> {
78+ insertGiftActivity(result)
79+ _successEvent .emit(
80+ NewTransactionSheetDetails (
81+ type = NewTransactionSheetType .LIGHTNING ,
82+ direction = NewTransactionSheetDirection .RECEIVED ,
83+ paymentHashOrTxId = result.paymentHashOrTxId,
84+ sats = result.sats,
85+ )
86+ )
87+ _navigationEvent .emit(GiftRoute .Success )
88+ }
89+ }
90+ },
91+ onFailure = { error ->
92+ handleGiftClaimError(error)
93+ }
94+ )
9395 } finally {
9496 isClaiming = false
9597 }
9698 }
9799
98- private suspend fun claimWithLiquidity () {
99- runCatching {
100- val invoice = lightningService.receive(
101- sat = null ,
102- description = " blocktank-gift-code:$code " ,
103- expirySecs = 3600u ,
104- )
105-
106- ServiceQueue .CORE .background {
107- giftPay(invoice = invoice)
108- }
109-
110- _navigationEvent .emit(GiftRoute .Success )
111- }.onFailure { e ->
112- handleGiftClaimError(e)
113- }
114- }
115-
116- private suspend fun claimWithoutLiquidity () {
117- runCatching {
118- check(lightningService.nodeId != null ) { " Node not started" }
119- val nodeId = lightningService.nodeId!!
120-
121- val order = ServiceQueue .CORE .background {
122- giftOrder(clientNodeId = nodeId, code = " blocktank-gift-code:$code " )
123- }
124-
125- check(order.orderId != null ) { " Order ID is nil" }
126- val orderId = order.orderId!!
127-
128- val openedOrder = blocktankRepo.openChannel(orderId).getOrThrow()
129-
130- val nowTimestamp = (System .currentTimeMillis() / 1000 ).toULong()
131-
132- val lightningActivity = com.synonym.bitkitcore.LightningActivity (
133- id = openedOrder.channel?.fundingTx?.id ? : orderId,
134- txType = PaymentType .RECEIVED ,
135- status = com.synonym.bitkitcore.PaymentState .SUCCEEDED ,
136- value = amount,
137- fee = 0u ,
138- invoice = openedOrder.payment?.bolt11Invoice?.request ? : " " ,
139- message = code,
140- timestamp = nowTimestamp,
141- preimage = null ,
142- createdAt = nowTimestamp,
143- updatedAt = null ,
144- )
145-
146- activityRepo.insertActivity(Activity .Lightning (lightningActivity)).getOrThrow()
147-
148- _successEvent .emit(
149- NewTransactionSheetDetails (
150- type = NewTransactionSheetType .LIGHTNING ,
151- direction = NewTransactionSheetDirection .RECEIVED ,
152- paymentHashOrTxId = openedOrder.channel?.fundingTx?.id ? : orderId,
153- sats = amount.toLong(),
154- )
155- )
156- _navigationEvent .emit(GiftRoute .Success )
157- }.onFailure { e ->
158- handleGiftClaimError(e)
159- }
100+ private suspend fun insertGiftActivity (result : GiftClaimResult .SuccessWithoutLiquidity ) {
101+ val nowTimestamp = nowTimestamp().epochSecond.toULong()
102+
103+ val lightningActivity = com.synonym.bitkitcore.LightningActivity (
104+ id = result.paymentHashOrTxId,
105+ txType = PaymentType .RECEIVED ,
106+ status = PaymentState .SUCCEEDED ,
107+ value = result.sats.toULong(),
108+ fee = 0u ,
109+ invoice = result.invoice,
110+ message = result.code,
111+ timestamp = nowTimestamp,
112+ preimage = null ,
113+ createdAt = nowTimestamp,
114+ updatedAt = null ,
115+ )
116+
117+ activityRepo.insertActivity(Activity .Lightning (lightningActivity)).getOrThrow()
160118 }
161119
162120 private suspend fun handleGiftClaimError (error : Throwable ) {
@@ -186,6 +144,5 @@ class GiftViewModel @Inject constructor(
186144 companion object {
187145 private const val TAG = " GiftViewModel"
188146 private const val NODE_STARTUP_TIMEOUT_MS = 30_000L
189- private const val PEER_CONNECTION_DELAY_MS = 2_000L
190147 }
191148}
0 commit comments