Skip to content

Commit be27a0b

Browse files
authored
Merge pull request #607 from synonymdev/fix/lnurl-pay
fix: use core LNURL-pay validation
2 parents d4c0c1d + c522b5c commit be27a0b

7 files changed

Lines changed: 36 additions & 27 deletions

File tree

Bitkit.xcodeproj/project.pbxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1201,7 +1201,7 @@
12011201
repositoryURL = "https://github.com/synonymdev/bitkit-core";
12021202
requirement = {
12031203
kind = exactVersion;
1204-
version = 0.1.64;
1204+
version = 0.1.74;
12051205
};
12061206
};
12071207
96E20CD22CB6D91A00C24149 /* XCRemoteSwiftPackageReference "CodeScanner" */ = {

Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Bitkit/Utilities/Lnurl.swift

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import BitkitCore
22
import Foundation
33

4-
// MARK: - Response Models
5-
6-
private struct LnurlPayResponse: Codable {
7-
let pr: String
8-
let routes: [String]
4+
struct LnurlPayInvoiceMismatchError: LocalizedError {
5+
var errorDescription: String? {
6+
return "The invoice did not match the requested payment. Payment cancelled."
7+
}
98
}
109

10+
// MARK: - Response Models
11+
1112
private struct LnurlWithdrawResponse: Codable {
1213
let status: String
1314
let reason: String?
@@ -116,37 +117,42 @@ private extension LnurlHelper {
116117
throw NSError(domain: "LNURL", code: -1, userInfo: [NSLocalizedDescriptionKey: errorMessage])
117118
}
118119
}
120+
121+
static func mapLnurlPayInvoiceError(_ error: Error) -> Error {
122+
if let lnurlError = error as? LnurlError {
123+
switch lnurlError {
124+
case .InvalidAmount, .AmountMismatch, .MetadataMismatch:
125+
return LnurlPayInvoiceMismatchError()
126+
default:
127+
break
128+
}
129+
}
130+
131+
return error
132+
}
119133
}
120134

121135
@MainActor
122136
struct LnurlHelper {
123-
/// Fetches a Lightning invoice from an LNURL pay callback
137+
/// Fetches a Lightning invoice for an LNURL pay request
124138
/// - Parameters:
125-
/// - callbackUrl: The LNURL callback URL
139+
/// - data: The LNURL pay data
126140
/// - amountMsats: The amount in millisatoshis to pay
127141
/// - comment: Optional comment to include with the payment
128142
/// - Returns: The bolt11 invoice string
129143
/// - Throws: Network or parsing errors
130144
static func fetchLnurlInvoice(
131-
callbackUrl: String,
145+
data: LnurlPayData,
132146
amountMsats: UInt64,
133147
comment: String? = nil
134148
) async throws -> String {
135-
var queryItems = [
136-
URLQueryItem(name: "amount", value: String(amountMsats)),
137-
]
138-
139-
// Add comment if provided
140-
if let comment, !comment.isEmpty {
141-
queryItems.append(URLQueryItem(name: "comment", value: comment))
149+
do {
150+
let invoice = try await getLnurlInvoiceForPayData(data: data, amountMsats: amountMsats, comment: comment)
151+
Logger.debug("Fetched LNURL pay invoice")
152+
return invoice
153+
} catch {
154+
throw mapLnurlPayInvoiceError(error)
142155
}
143-
144-
let callbackURL = try buildUrl(baseUrl: callbackUrl, queryItems: queryItems)
145-
let responseString = try await makeHttpGetRequest(url: callbackURL)
146-
let lnurlResponse = try parseJsonResponse(responseString, as: LnurlPayResponse.self)
147-
148-
Logger.debug("Extracted bolt11 invoice: \(lnurlResponse.pr)")
149-
return lnurlResponse.pr
150156
}
151157

152158
/// Handles LNURL Withdraw Requests

Bitkit/ViewModels/Trezor/TrezorViewModel.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,8 @@ class TrezorViewModel {
951951
return "Invalid transaction ID: \(errorDetails)"
952952
case let .TransactionNotFound(errorDetails):
953953
return "Transaction not found: \(errorDetails)"
954+
case let .WatcherError(errorDetails):
955+
return "Watcher error: \(errorDetails)"
954956
}
955957
}
956958
if let appError = error as? AppError,

Bitkit/Views/Wallets/Send/LnurlPayConfirm.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ struct LnurlPayConfirm: View {
194194

195195
// Fetch the Lightning invoice from LNURL
196196
let bolt11 = try await LnurlHelper.fetchLnurlInvoice(
197-
callbackUrl: lnurlPayData.callback,
197+
data: lnurlPayData,
198198
amountMsats: amountMsats,
199199
comment: comment.isEmpty ? nil : comment
200200
)

Bitkit/Views/Wallets/Send/SendQuickpay.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ struct SendQuickpay: View {
4848
wallet.sendAmountSats = lnurlPayData.minSendableSat
4949

5050
bolt11Invoice = try await LnurlHelper.fetchLnurlInvoice(
51-
callbackUrl: lnurlPayData.callback,
51+
data: lnurlPayData,
5252
amountMsats: lnurlPayData.callbackAmountMsats()
5353
)
5454
} else if let scannedInvoice = app.scannedLightningInvoice {

changelog.d/hotfix/607.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improved LNURL-pay invoice validation.

0 commit comments

Comments
 (0)