Skip to content

Commit 6170ff3

Browse files
ovitrifclaude
andcommitted
refactor: add msatCeilOf/msatFloorOf sugar functions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1e04e86 commit 6170ff3

13 files changed

Lines changed: 49 additions & 41 deletions

File tree

app/src/main/java/to/bitkit/domain/commands/NotifyPaymentReceivedHandler.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import to.bitkit.models.NotificationDetails
1818
import to.bitkit.models.PrimaryDisplay
1919
import to.bitkit.models.formatToModernDisplay
2020
import to.bitkit.repositories.ActivityRepo
21-
import to.bitkit.models.MSat
21+
import to.bitkit.models.msatCeilOf
2222
import to.bitkit.repositories.CurrencyRepo
2323
import to.bitkit.utils.Logger
2424
import javax.inject.Inject
@@ -98,7 +98,7 @@ class NotifyPaymentReceivedHandler @Inject constructor(
9898
is NotifyPaymentReceived.Command.Onchain -> command.event.txid
9999
},
100100
sats = when (command) {
101-
is NotifyPaymentReceived.Command.Lightning -> MSat(command.event.amountMsat).ceil().toLong()
101+
is NotifyPaymentReceived.Command.Lightning -> msatCeilOf(command.event.amountMsat).toLong()
102102
is NotifyPaymentReceived.Command.Onchain -> command.event.details.amountSats
103103
},
104104
)

app/src/main/java/to/bitkit/ext/ChannelDetails.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package to.bitkit.ext
33
import org.lightningdevkit.ldknode.ChannelConfig
44
import org.lightningdevkit.ldknode.ChannelDetails
55
import org.lightningdevkit.ldknode.MaxDustHtlcExposure
6-
import to.bitkit.models.MSat
6+
import to.bitkit.models.msatFloorOf
77

88
/**
99
* Calculates our total balance in the channel (see `value_to_self_msat` in rust-lightning).
@@ -19,7 +19,7 @@ val ChannelDetails.amountOnClose: ULong
1919
@Suppress("ForbiddenComment")
2020
get() {
2121
// TODO: use channelDetails.claimableOnCloseSats
22-
val outboundCapacitySat = MSat(this.outboundCapacityMsat).floor()
22+
val outboundCapacitySat = msatFloorOf(this.outboundCapacityMsat)
2323
val ourReserve = this.unspendablePunishmentReserve ?: 0u
2424

2525
return outboundCapacitySat + ourReserve
@@ -33,13 +33,13 @@ fun List<ChannelDetails>.filterPending(): List<ChannelDetails> = this.filterNot
3333

3434
/** Returns a limit in sats as close as possible to the HTLC limit we can currently send. */
3535
fun List<ChannelDetails>?.totalNextOutboundHtlcLimitSats(): ULong = this?.filter { it.isUsable }
36-
?.sumOf { MSat(it.nextOutboundHtlcLimitMsat).floor() }
36+
?.sumOf { msatFloorOf(it.nextOutboundHtlcLimitMsat) }
3737
?: 0u
3838

3939
/** Calculates the total remote balance (inbound capacity) from open channels. */
4040
fun List<ChannelDetails>.calculateRemoteBalance(): ULong = this
4141
.filterOpen()
42-
.sumOf { MSat(it.inboundCapacityMsat).floor() }
42+
.sumOf { msatFloorOf(it.inboundCapacityMsat) }
4343

4444
fun createChannelDetails(): ChannelDetails = ChannelDetails(
4545
channelId = "channelId",

app/src/main/java/to/bitkit/ext/Lnurl.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ package to.bitkit.ext
33
import com.synonym.bitkitcore.LnurlPayData
44
import com.synonym.bitkitcore.LnurlWithdrawData
55
import to.bitkit.models.MSat
6+
import to.bitkit.models.msatCeilOf
7+
import to.bitkit.models.msatFloorOf
68

79
fun LnurlPayData.commentAllowed(): Boolean = commentAllowed?.let { it > 0u } == true
8-
fun LnurlPayData.maxSendableSat(): ULong = MSat(maxSendable).floor()
9-
fun LnurlPayData.minSendableSat(): ULong = MSat(minSendable).ceil()
10+
fun LnurlPayData.maxSendableSat(): ULong = msatFloorOf(maxSendable)
11+
fun LnurlPayData.minSendableSat(): ULong = msatCeilOf(minSendable)
1012

1113
/**
1214
* True when the LNURL-pay endpoint specifies a single exact amount.
@@ -30,8 +32,8 @@ fun LnurlPayData.isFixedAmount(): Boolean =
3032
fun LnurlPayData.callbackAmountMsats(userSats: ULong? = null): ULong =
3133
if (isFixedAmount()) minSendable else (userSats ?: minSendableSat()) * MSat.PER_SAT
3234

33-
fun LnurlWithdrawData.minWithdrawableSat(): ULong = MSat(minWithdrawable ?: 0u).ceil()
34-
fun LnurlWithdrawData.maxWithdrawableSat(): ULong = MSat(maxWithdrawable).floor()
35+
fun LnurlWithdrawData.minWithdrawableSat(): ULong = msatCeilOf(minWithdrawable ?: 0u)
36+
fun LnurlWithdrawData.maxWithdrawableSat(): ULong = msatFloorOf(maxWithdrawable)
3537

3638
/**
3739
* True when the LNURL-withdraw endpoint specifies a single exact amount,
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package to.bitkit.ext
22

33
import org.lightningdevkit.ldknode.PaymentDetails
4-
import to.bitkit.models.MSat
4+
import to.bitkit.models.msatCeilOf
55

66
val PaymentDetails.amountSats: ULong?
7-
get() = amountMsat?.let { MSat(it).ceil() }
7+
get() = amountMsat?.let { msatCeilOf(it) }

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import to.bitkit.ext.amountOnClose
2626
import to.bitkit.ext.toUserMessage
2727
import to.bitkit.models.BITCOIN_SYMBOL
2828
import to.bitkit.models.BlocktankNotificationType
29-
import to.bitkit.models.MSat
29+
import to.bitkit.models.msatCeilOf
3030
import to.bitkit.models.BlocktankNotificationType.cjitPaymentArrived
3131
import to.bitkit.models.BlocktankNotificationType.incomingHtlc
3232
import to.bitkit.models.BlocktankNotificationType.mutualClose
@@ -193,7 +193,7 @@ class WakeNodeWorker @AssistedInject constructor(
193193
showDetails: Boolean,
194194
hiddenBody: String,
195195
) {
196-
val sats = MSat(event.amountMsat).ceil()
196+
val sats = msatCeilOf(event.amountMsat)
197197
// Save for UI to pick up
198198
cacheStore.setBackgroundReceive(
199199
NewTransactionSheetDetails(

app/src/main/java/to/bitkit/models/MSat.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,9 @@ value class MSat(val value: ULong) {
1818
/** Truncate sub-sat remainder. Use for fees and upper bounds. */
1919
fun floor(): ULong = value / PER_SAT
2020
}
21+
22+
/** Syntactic sugar for [MSat.ceil]. */
23+
fun msatCeilOf(msat: ULong): ULong = MSat(msat).ceil()
24+
25+
/** Syntactic sugar for [MSat.floor]. */
26+
fun msatFloorOf(msat: ULong): ULong = MSat(msat).floor()

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import to.bitkit.ext.toHex
3232
import to.bitkit.models.ALL_ADDRESS_TYPE_STRINGS
3333
import to.bitkit.models.AddressModel
3434
import to.bitkit.models.BalanceState
35-
import to.bitkit.models.MSat
35+
import to.bitkit.models.msatFloorOf
3636
import to.bitkit.models.DEFAULT_ADDRESS_TYPE_STRING
3737
import to.bitkit.models.toDerivationPath
3838
import to.bitkit.services.CoreService
@@ -566,7 +566,7 @@ class WalletRepo @Inject constructor(
566566
val channels = lightningRepo.lightningState.value.channels
567567
if (channels.filterOpen().isEmpty()) return@runCatching false
568568

569-
val inboundBalanceSats = channels.sumOf { MSat(it.inboundCapacityMsat).floor() }
569+
val inboundBalanceSats = channels.sumOf { msatFloorOf(it.inboundCapacityMsat) }
570570

571571
return@runCatching (_walletState.value.bip21AmountSats ?: 0uL) >= inboundBalanceSats
572572
}.onFailure {

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ import to.bitkit.data.CacheStore
7272
import to.bitkit.data.SettingsStore
7373
import to.bitkit.env.Env
7474
import to.bitkit.ext.amountSats
75-
import to.bitkit.models.MSat
75+
import to.bitkit.models.msatFloorOf
7676
import to.bitkit.ext.channelId
7777
import to.bitkit.ext.create
7878
import to.bitkit.ext.latestSpendingTxid
@@ -502,7 +502,7 @@ class ActivityService(
502502
value = payment.amountSats ?: 0u,
503503
invoice = kind.bolt11 ?: "Loading...",
504504
timestamp = payment.latestUpdateTimestamp,
505-
fee = MSat(payment.feePaidMsat ?: 0u).floor(),
505+
fee = msatFloorOf(payment.feePaidMsat ?: 0u),
506506
message = kind.description.orEmpty(),
507507
preimage = kind.preimage,
508508
seenAt = null,
@@ -611,7 +611,7 @@ class ActivityService(
611611
ldkValue
612612
}
613613

614-
val ldkFeeSats = MSat(ldkFeeMsat).floor()
614+
val ldkFeeSats = msatFloorOf(ldkFeeMsat)
615615
val updatedFee = if (existingActivity.v1.fee == 0uL && ldkFeeSats > 0uL) ldkFeeSats else existingActivity.v1.fee
616616

617617
val updatedOnChain = existingActivity.v1.copy(
@@ -650,7 +650,7 @@ class ActivityService(
650650
txType = payment.direction.toPaymentType(),
651651
txId = kind.txid,
652652
value = payment.amountSats ?: 0u,
653-
fee = MSat(payment.feePaidMsat ?: 0u).floor(),
653+
fee = msatFloorOf(payment.feePaidMsat ?: 0u),
654654
address = resolvedAddress ?: "Loading...",
655655
timestamp = activityTimestamp,
656656
confirmed = confirmationData.isConfirmed,

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ import to.bitkit.env.Env
4949
import to.bitkit.ext.totalNextOutboundHtlcLimitSats
5050
import to.bitkit.ext.uByteList
5151
import to.bitkit.ext.uri
52-
import to.bitkit.models.MSat
52+
import to.bitkit.models.msatFloorOf
5353
import to.bitkit.models.OpenChannelResult
5454
import to.bitkit.models.toAddressType
5555
import to.bitkit.utils.AppError
@@ -695,7 +695,7 @@ class LightningService @Inject constructor(
695695
return@background runCatching {
696696
val invoice = Bolt11Invoice.fromStr(bolt11)
697697
val feesMsat = node.bolt11Payment().estimateRoutingFees(invoice)
698-
val feeSat = MSat(feesMsat).floor()
698+
val feeSat = msatFloorOf(feesMsat)
699699
Result.success(feeSat)
700700
}.getOrElse {
701701
Result.failure(if (it is NodeException) LdkError(it) else it)
@@ -711,7 +711,7 @@ class LightningService @Inject constructor(
711711
val invoice = Bolt11Invoice.fromStr(bolt11)
712712
val amountMsat = amountSats * 1000u
713713
val feesMsat = node.bolt11Payment().estimateRoutingFeesUsingAmount(invoice, amountMsat)
714-
val feeSat = MSat(feesMsat).floor()
714+
val feeSat = msatFloorOf(feesMsat)
715715
Result.success(feeSat)
716716
}.getOrElse {
717717
Result.failure(if (it is NodeException) LdkError(it) else it)
@@ -729,7 +729,7 @@ class LightningService @Inject constructor(
729729

730730
val invoiceAmountMsat = bolt11Invoice.amountMilliSatoshis()
731731
Logger.debug(
732-
"sendProbes: invoiceAmountMsat=$invoiceAmountMsat (${invoiceAmountMsat?.let { MSat(it).floor() }} sats)",
732+
"sendProbes: invoiceAmountMsat=$invoiceAmountMsat (${invoiceAmountMsat?.let { msatFloorOf(it) }} sats)",
733733
context = TAG
734734
)
735735

@@ -752,8 +752,8 @@ class LightningService @Inject constructor(
752752

753753
val invoiceAmountMsat = bolt11Invoice.amountMilliSatoshis()
754754
Logger.debug(
755-
"sendProbesUsingAmount: customAmountMsat=$amountMsat (${MSat(amountMsat).floor()} sats), " +
756-
"invoiceAmountMsat=$invoiceAmountMsat (${invoiceAmountMsat?.let { MSat(it).floor() }} sats)",
755+
"sendProbesUsingAmount: customAmountMsat=$amountMsat (${msatFloorOf(amountMsat)} sats), " +
756+
"invoiceAmountMsat=$invoiceAmountMsat (${invoiceAmountMsat?.let { msatFloorOf(it) }} sats)",
757757
context = TAG
758758
)
759759

app/src/main/java/to/bitkit/ui/NodeInfoScreen.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ import to.bitkit.ext.createChannelDetails
5050
import to.bitkit.ext.ellipsisMiddle
5151
import to.bitkit.ext.formatToString
5252
import to.bitkit.ext.uri
53-
import to.bitkit.models.MSat
53+
import to.bitkit.models.msatFloorOf
5454
import to.bitkit.models.NodeLifecycleState
5555
import to.bitkit.models.NodePeer
5656
import to.bitkit.models.alias
@@ -337,8 +337,8 @@ private fun ChannelsSection(
337337
}
338338
LightningChannel(
339339
capacity = (channel.channelValueSats).toLong(),
340-
localBalance = MSat(channel.outboundCapacityMsat).floor().toLong(),
341-
remoteBalance = MSat(channel.inboundCapacityMsat).floor().toLong(),
340+
localBalance = msatFloorOf(channel.outboundCapacityMsat).toLong(),
341+
remoteBalance = msatFloorOf(channel.inboundCapacityMsat).toLong(),
342342
status = if (channel.isChannelReady) ChannelStatusUi.OPEN else ChannelStatusUi.PENDING,
343343
)
344344
VerticalSpacer(8.dp)
@@ -357,25 +357,25 @@ private fun ChannelsSection(
357357
)
358358
ChannelDetailRow(
359359
title = stringResource(R.string.lightning__inbound_capacity),
360-
value = "${MSat(channel.inboundCapacityMsat).floor().formatToModernDisplay()}",
360+
value = "${msatFloorOf(channel.inboundCapacityMsat).formatToModernDisplay()}",
361361
)
362362
ChannelDetailRow(
363363
title = stringResource(R.string.lightning__inbound_htlc_max),
364364
value = "${
365-
(channel.inboundHtlcMaximumMsat?.let { MSat(it).floor() } ?: 0u).formatToModernDisplay()
365+
(channel.inboundHtlcMaximumMsat?.let { msatFloorOf(it) } ?: 0u).formatToModernDisplay()
366366
}",
367367
)
368368
ChannelDetailRow(
369369
title = stringResource(R.string.lightning__inbound_htlc_min),
370-
value = "${MSat(channel.inboundHtlcMinimumMsat).floor().formatToModernDisplay()}",
370+
value = "${msatFloorOf(channel.inboundHtlcMinimumMsat).formatToModernDisplay()}",
371371
)
372372
ChannelDetailRow(
373373
title = stringResource(R.string.lightning__next_outbound_htlc_limit),
374-
value = "${MSat(channel.nextOutboundHtlcLimitMsat).floor().formatToModernDisplay()}",
374+
value = "${msatFloorOf(channel.nextOutboundHtlcLimitMsat).formatToModernDisplay()}",
375375
)
376376
ChannelDetailRow(
377377
title = stringResource(R.string.lightning__next_outbound_htlc_min),
378-
value = "${MSat(channel.nextOutboundHtlcMinimumMsat).floor().formatToModernDisplay()}",
378+
value = "${msatFloorOf(channel.nextOutboundHtlcMinimumMsat).formatToModernDisplay()}",
379379
)
380380
ChannelDetailRow(
381381
title = stringResource(R.string.common__confirmations),

0 commit comments

Comments
 (0)