Skip to content

Commit 15889b8

Browse files
committed
refactor: use MSat for conversions
1 parent a9ae186 commit 15889b8

12 files changed

Lines changed: 43 additions & 48 deletions

File tree

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +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
2122
import to.bitkit.repositories.CurrencyRepo
2223
import to.bitkit.utils.Logger
2324
import javax.inject.Inject
@@ -97,7 +98,7 @@ class NotifyPaymentReceivedHandler @Inject constructor(
9798
is NotifyPaymentReceived.Command.Onchain -> command.event.txid
9899
},
99100
sats = when (command) {
100-
is NotifyPaymentReceived.Command.Lightning -> ((command.event.amountMsat + 999u) / 1000u).toLong()
101+
is NotifyPaymentReceived.Command.Lightning -> MSat(command.event.amountMsat).ceil().toLong()
101102
is NotifyPaymentReceived.Command.Onchain -> command.event.details.amountSats
102103
},
103104
)

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +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
67

78
/**
89
* Calculates our total balance in the channel (see `value_to_self_msat` in rust-lightning).
@@ -18,7 +19,7 @@ val ChannelDetails.amountOnClose: ULong
1819
@Suppress("ForbiddenComment")
1920
get() {
2021
// TODO: use channelDetails.claimableOnCloseSats
21-
val outboundCapacitySat = this.outboundCapacityMsat / 1000u
22+
val outboundCapacitySat = MSat(this.outboundCapacityMsat).floor()
2223
val ourReserve = this.unspendablePunishmentReserve ?: 0u
2324

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

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

3839
/** Calculates the total remote balance (inbound capacity) from open channels. */
3940
fun List<ChannelDetails>.calculateRemoteBalance(): ULong = this
4041
.filterOpen()
41-
.sumOf { it.inboundCapacityMsat / 1000u }
42+
.sumOf { MSat(it.inboundCapacityMsat).floor() }
4243

4344
fun createChannelDetails(): ChannelDetails = ChannelDetails(
4445
channelId = "channelId",

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

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,11 @@ package to.bitkit.ext
22

33
import com.synonym.bitkitcore.LnurlPayData
44
import com.synonym.bitkitcore.LnurlWithdrawData
5-
6-
private const val MSATS_PER_SAT: ULong = 1000u
7-
8-
/**
9-
* LNURL amounts are expressed in millisatoshis (msat).
10-
*
11-
* When converting a minimum bound to whole sats we must round up:
12-
* `minSendable = 100500 msat` means the minimum payable amount is `101 sat` (not `100 sat`).
13-
*/
14-
private fun msatsToSatsCeil(msats: ULong): ULong {
15-
val quotient = msats / MSATS_PER_SAT
16-
val remainder = msats % MSATS_PER_SAT
17-
return when (remainder) {
18-
0uL -> quotient
19-
else -> quotient + 1uL
20-
}
21-
}
5+
import to.bitkit.models.MSat
226

237
fun LnurlPayData.commentAllowed(): Boolean = commentAllowed?.let { it > 0u } == true
24-
fun LnurlPayData.maxSendableSat(): ULong = maxSendable / MSATS_PER_SAT
25-
fun LnurlPayData.minSendableSat(): ULong = msatsToSatsCeil(minSendable)
8+
fun LnurlPayData.maxSendableSat(): ULong = MSat(maxSendable).floor()
9+
fun LnurlPayData.minSendableSat(): ULong = MSat(minSendable).ceil()
2610

2711
/**
2812
* True when the LNURL-pay endpoint specifies a single exact amount.
@@ -44,10 +28,10 @@ fun LnurlPayData.isFixedAmount(): Boolean =
4428
* For variable-amount requests the user-selected sat amount is converted to msats.
4529
*/
4630
fun LnurlPayData.callbackAmountMsats(userSats: ULong? = null): ULong =
47-
if (isFixedAmount()) minSendable else (userSats ?: minSendableSat()) * MSATS_PER_SAT
31+
if (isFixedAmount()) minSendable else (userSats ?: minSendableSat()) * 1000u
4832

49-
fun LnurlWithdrawData.minWithdrawableSat(): ULong = msatsToSatsCeil(minWithdrawable ?: 0u)
50-
fun LnurlWithdrawData.maxWithdrawableSat(): ULong = maxWithdrawable / MSATS_PER_SAT
33+
fun LnurlWithdrawData.minWithdrawableSat(): ULong = MSat(minWithdrawable ?: 0u).ceil()
34+
fun LnurlWithdrawData.maxWithdrawableSat(): ULong = MSat(maxWithdrawable).floor()
5135

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

33
import org.lightningdevkit.ldknode.PaymentDetails
4+
import to.bitkit.models.MSat
45

56
val PaymentDetails.amountSats: ULong?
6-
get() = amountMsat?.let { (it + 999u) / 1000u }
7+
get() = amountMsat?.let { MSat(it).ceil() }

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +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
2930
import to.bitkit.models.BlocktankNotificationType.cjitPaymentArrived
3031
import to.bitkit.models.BlocktankNotificationType.incomingHtlc
3132
import to.bitkit.models.BlocktankNotificationType.mutualClose
@@ -192,7 +193,7 @@ class WakeNodeWorker @AssistedInject constructor(
192193
showDetails: Boolean,
193194
hiddenBody: String,
194195
) {
195-
val sats = (event.amountMsat + 999u) / 1000u
196+
val sats = MSat(event.amountMsat).ceil()
196197
// Save for UI to pick up
197198
cacheStore.setBackgroundReceive(
198199
NewTransactionSheetDetails(

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +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
3536
import to.bitkit.models.DEFAULT_ADDRESS_TYPE_STRING
3637
import to.bitkit.models.toDerivationPath
3738
import to.bitkit.services.CoreService
@@ -565,7 +566,7 @@ class WalletRepo @Inject constructor(
565566
val channels = lightningRepo.lightningState.value.channels
566567
if (channels.filterOpen().isEmpty()) return@runCatching false
567568

568-
val inboundBalanceSats = channels.sumOf { it.inboundCapacityMsat / 1000u }
569+
val inboundBalanceSats = channels.sumOf { MSat(it.inboundCapacityMsat).floor() }
569570

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

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +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
7576
import to.bitkit.ext.channelId
7677
import to.bitkit.ext.create
7778
import to.bitkit.ext.latestSpendingTxid
@@ -501,7 +502,7 @@ class ActivityService(
501502
value = payment.amountSats ?: 0u,
502503
invoice = kind.bolt11 ?: "Loading...",
503504
timestamp = payment.latestUpdateTimestamp,
504-
fee = (payment.feePaidMsat ?: 0u) / 1000u,
505+
fee = MSat(payment.feePaidMsat ?: 0u).floor(),
505506
message = kind.description.orEmpty(),
506507
preimage = kind.preimage,
507508
seenAt = null,
@@ -610,7 +611,7 @@ class ActivityService(
610611
ldkValue
611612
}
612613

613-
val ldkFeeSats = ldkFeeMsat / 1000u
614+
val ldkFeeSats = MSat(ldkFeeMsat).floor()
614615
val updatedFee = if (existingActivity.v1.fee == 0uL && ldkFeeSats > 0uL) ldkFeeSats else existingActivity.v1.fee
615616

616617
val updatedOnChain = existingActivity.v1.copy(
@@ -649,7 +650,7 @@ class ActivityService(
649650
txType = payment.direction.toPaymentType(),
650651
txId = kind.txid,
651652
value = payment.amountSats ?: 0u,
652-
fee = (payment.feePaidMsat ?: 0u) / 1000u,
653+
fee = MSat(payment.feePaidMsat ?: 0u).floor(),
653654
address = resolvedAddress ?: "Loading...",
654655
timestamp = activityTimestamp,
655656
confirmed = confirmationData.isConfirmed,

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +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
5253
import to.bitkit.models.OpenChannelResult
5354
import to.bitkit.models.toAddressType
5455
import to.bitkit.utils.AppError
@@ -694,7 +695,7 @@ class LightningService @Inject constructor(
694695
return@background runCatching {
695696
val invoice = Bolt11Invoice.fromStr(bolt11)
696697
val feesMsat = node.bolt11Payment().estimateRoutingFees(invoice)
697-
val feeSat = feesMsat / 1000u
698+
val feeSat = MSat(feesMsat).floor()
698699
Result.success(feeSat)
699700
}.getOrElse {
700701
Result.failure(if (it is NodeException) LdkError(it) else it)
@@ -710,7 +711,7 @@ class LightningService @Inject constructor(
710711
val invoice = Bolt11Invoice.fromStr(bolt11)
711712
val amountMsat = amountSats * 1000u
712713
val feesMsat = node.bolt11Payment().estimateRoutingFeesUsingAmount(invoice, amountMsat)
713-
val feeSat = feesMsat / 1000u
714+
val feeSat = MSat(feesMsat).floor()
714715
Result.success(feeSat)
715716
}.getOrElse {
716717
Result.failure(if (it is NodeException) LdkError(it) else it)
@@ -728,7 +729,7 @@ class LightningService @Inject constructor(
728729

729730
val invoiceAmountMsat = bolt11Invoice.amountMilliSatoshis()
730731
Logger.debug(
731-
"sendProbes: invoiceAmountMsat=$invoiceAmountMsat (${invoiceAmountMsat?.let { it / 1000u }} sats)",
732+
"sendProbes: invoiceAmountMsat=$invoiceAmountMsat (${invoiceAmountMsat?.let { MSat(it).floor() }} sats)",
732733
context = TAG
733734
)
734735

@@ -751,8 +752,8 @@ class LightningService @Inject constructor(
751752

752753
val invoiceAmountMsat = bolt11Invoice.amountMilliSatoshis()
753754
Logger.debug(
754-
"sendProbesUsingAmount: customAmountMsat=$amountMsat (${amountMsat / 1000u} sats), " +
755-
"invoiceAmountMsat=$invoiceAmountMsat (${invoiceAmountMsat?.let { it / 1000u }} sats)",
755+
"sendProbesUsingAmount: customAmountMsat=$amountMsat (${MSat(amountMsat).floor()} sats), " +
756+
"invoiceAmountMsat=$invoiceAmountMsat (${invoiceAmountMsat?.let { MSat(it).floor() }} sats)",
756757
context = TAG
757758
)
758759

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +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
5354
import to.bitkit.models.NodeLifecycleState
5455
import to.bitkit.models.NodePeer
5556
import to.bitkit.models.alias
@@ -336,8 +337,8 @@ private fun ChannelsSection(
336337
}
337338
LightningChannel(
338339
capacity = (channel.channelValueSats).toLong(),
339-
localBalance = (channel.outboundCapacityMsat / 1000u).toLong(),
340-
remoteBalance = (channel.inboundCapacityMsat / 1000u).toLong(),
340+
localBalance = MSat(channel.outboundCapacityMsat).floor().toLong(),
341+
remoteBalance = MSat(channel.inboundCapacityMsat).floor().toLong(),
341342
status = if (channel.isChannelReady) ChannelStatusUi.OPEN else ChannelStatusUi.PENDING,
342343
)
343344
VerticalSpacer(8.dp)
@@ -356,23 +357,23 @@ private fun ChannelsSection(
356357
)
357358
ChannelDetailRow(
358359
title = stringResource(R.string.lightning__inbound_capacity),
359-
value = "${(channel.inboundCapacityMsat / 1000u).formatToModernDisplay()}",
360+
value = "${MSat(channel.inboundCapacityMsat).floor().formatToModernDisplay()}",
360361
)
361362
ChannelDetailRow(
362363
title = stringResource(R.string.lightning__inbound_htlc_max),
363-
value = "${(channel.inboundHtlcMaximumMsat?.div(1000u) ?: 0u).formatToModernDisplay()}",
364+
value = "${(channel.inboundHtlcMaximumMsat?.let { MSat(it).floor() } ?: 0u).formatToModernDisplay()}",
364365
)
365366
ChannelDetailRow(
366367
title = stringResource(R.string.lightning__inbound_htlc_min),
367-
value = "${(channel.inboundHtlcMinimumMsat / 1000u).formatToModernDisplay()}",
368+
value = "${MSat(channel.inboundHtlcMinimumMsat).floor().formatToModernDisplay()}",
368369
)
369370
ChannelDetailRow(
370371
title = stringResource(R.string.lightning__next_outbound_htlc_limit),
371-
value = "${(channel.nextOutboundHtlcLimitMsat / 1000u).formatToModernDisplay()}",
372+
value = "${MSat(channel.nextOutboundHtlcLimitMsat).floor().formatToModernDisplay()}",
372373
)
373374
ChannelDetailRow(
374375
title = stringResource(R.string.lightning__next_outbound_htlc_min),
375-
value = "${(channel.nextOutboundHtlcMinimumMsat / 1000u).formatToModernDisplay()}",
376+
value = "${MSat(channel.nextOutboundHtlcMinimumMsat).floor().formatToModernDisplay()}",
376377
)
377378
ChannelDetailRow(
378379
title = stringResource(R.string.common__confirmations),

app/src/main/java/to/bitkit/ui/settings/lightning/ChannelDetailScreen.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import to.bitkit.ext.DatePattern
6060
import to.bitkit.ext.amountOnClose
6161
import to.bitkit.ext.createChannelDetails
6262
import to.bitkit.ext.setClipboardText
63+
import to.bitkit.models.MSat
6364
import to.bitkit.models.Toast
6465
import to.bitkit.ui.Routes
6566
import to.bitkit.ui.appViewModel
@@ -221,7 +222,7 @@ private fun ChannelDetailContent(
221222

222223
val capacity = channel.details.channelValueSats.toLong()
223224
val localBalance = channel.details.amountOnClose.toLong()
224-
val remoteBalance = (channel.details.inboundCapacityMsat / 1000u).toLong()
225+
val remoteBalance = MSat(channel.details.inboundCapacityMsat).floor().toLong()
225226
val reserveBalance = (channel.details.unspendablePunishmentReserve ?: 0u).toLong()
226227

227228
PullToRefreshBox(
@@ -376,7 +377,7 @@ private fun ChannelDetailContent(
376377
name = stringResource(R.string.lightning__base_fee),
377378
valueContent = {
378379
MoneyCaptionB(
379-
sats = (channel.details.config.forwardingFeeBaseMsat / 1000u).toLong(),
380+
sats = MSat(channel.details.config.forwardingFeeBaseMsat.toULong()).floor().toLong(),
380381
symbol = true
381382
)
382383
}

0 commit comments

Comments
 (0)