Skip to content

Commit 15daf50

Browse files
committed
fix: correct lnurl msat to sat min rounding
1 parent 364e0a1 commit 15daf50

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import Foundation
2+
3+
enum LnurlAmountConversion {
4+
/// LNURL `minSendable` / `maxSendable` values are expressed in millisatoshis (msat).
5+
///
6+
/// The UI and amount input operate in whole sats. When converting a minimum bound to sats we must round up:
7+
/// `minSendable = 100500 msat` means the minimum payable amount is `101 sat` (not `100 sat`).
8+
static func satsCeil(fromMsats msats: UInt64) -> UInt64 {
9+
let quotient = msats / Env.msatsPerSat
10+
let remainder = msats % Env.msatsPerSat
11+
return remainder == 0 ? quotient : quotient + 1
12+
}
13+
14+
/// Converts msats → sats by rounding down (safe for maximum bounds).
15+
static func satsFloor(fromMsats msats: UInt64) -> UInt64 {
16+
msats / Env.msatsPerSat
17+
}
18+
}

Bitkit/ViewModels/AppViewModel.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,8 @@ extension AppViewModel {
253253
}
254254

255255
var normalizedData = data
256-
normalizedData.minSendable = max(1, normalizedData.minSendable / Env.msatsPerSat)
257-
normalizedData.maxSendable = max(normalizedData.minSendable, normalizedData.maxSendable / Env.msatsPerSat)
256+
normalizedData.minSendable = max(1, LnurlAmountConversion.satsCeil(fromMsats: normalizedData.minSendable))
257+
normalizedData.maxSendable = max(normalizedData.minSendable, LnurlAmountConversion.satsFloor(fromMsats: normalizedData.maxSendable))
258258

259259
// Check if user has enough lightning balance to pay the minimum amount
260260
let lightningBalance = lightningService.balances?.totalLightningBalanceSats ?? 0
@@ -292,8 +292,8 @@ extension AppViewModel {
292292
}
293293

294294
var normalizedData = data
295-
let minSats = max(1, minMsats / Env.msatsPerSat)
296-
let maxSats = max(minSats, maxMsats / Env.msatsPerSat)
295+
let minSats = max(1, LnurlAmountConversion.satsCeil(fromMsats: minMsats))
296+
let maxSats = max(minSats, LnurlAmountConversion.satsFloor(fromMsats: maxMsats))
297297
normalizedData.minWithdrawable = minSats
298298
normalizedData.maxWithdrawable = maxSats
299299

0 commit comments

Comments
 (0)