Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Bitkit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1201,7 +1201,7 @@
repositoryURL = "https://github.com/synonymdev/bitkit-core";
requirement = {
kind = exactVersion;
version = 0.1.64;
version = 0.1.74;
};
};
96E20CD22CB6D91A00C24149 /* XCRemoteSwiftPackageReference "CodeScanner" */ = {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 28 additions & 22 deletions Bitkit/Utilities/Lnurl.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import BitkitCore
import Foundation

// MARK: - Response Models

private struct LnurlPayResponse: Codable {
let pr: String
let routes: [String]
struct LnurlPayInvoiceMismatchError: LocalizedError {
var errorDescription: String? {
return "The invoice did not match the requested payment. Payment cancelled."
}
}

// MARK: - Response Models

private struct LnurlWithdrawResponse: Codable {
let status: String
let reason: String?
Expand Down Expand Up @@ -116,37 +117,42 @@ private extension LnurlHelper {
throw NSError(domain: "LNURL", code: -1, userInfo: [NSLocalizedDescriptionKey: errorMessage])
}
}

static func mapLnurlPayInvoiceError(_ error: Error) -> Error {
if let lnurlError = error as? LnurlError {
switch lnurlError {
case .InvalidAmount, .AmountMismatch, .MetadataMismatch:
return LnurlPayInvoiceMismatchError()
default:
break
}
}

return error
}
}

@MainActor
struct LnurlHelper {
/// Fetches a Lightning invoice from an LNURL pay callback
/// Fetches a Lightning invoice for an LNURL pay request
/// - Parameters:
/// - callbackUrl: The LNURL callback URL
/// - data: The LNURL pay data
/// - amountMsats: The amount in millisatoshis to pay
/// - comment: Optional comment to include with the payment
/// - Returns: The bolt11 invoice string
/// - Throws: Network or parsing errors
static func fetchLnurlInvoice(
callbackUrl: String,
data: LnurlPayData,
amountMsats: UInt64,
comment: String? = nil
) async throws -> String {
var queryItems = [
URLQueryItem(name: "amount", value: String(amountMsats)),
]

// Add comment if provided
if let comment, !comment.isEmpty {
queryItems.append(URLQueryItem(name: "comment", value: comment))
do {
let invoice = try await getLnurlInvoiceForPayData(data: data, amountMsats: amountMsats, comment: comment)
Logger.debug("Fetched LNURL pay invoice")
return invoice
} catch {
throw mapLnurlPayInvoiceError(error)
}

let callbackURL = try buildUrl(baseUrl: callbackUrl, queryItems: queryItems)
let responseString = try await makeHttpGetRequest(url: callbackURL)
let lnurlResponse = try parseJsonResponse(responseString, as: LnurlPayResponse.self)

Logger.debug("Extracted bolt11 invoice: \(lnurlResponse.pr)")
return lnurlResponse.pr
}

/// Handles LNURL Withdraw Requests
Expand Down
2 changes: 2 additions & 0 deletions Bitkit/ViewModels/Trezor/TrezorViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,8 @@ class TrezorViewModel {
return "Invalid transaction ID: \(errorDetails)"
case let .TransactionNotFound(errorDetails):
return "Transaction not found: \(errorDetails)"
case let .WatcherError(errorDetails):
return "Watcher error: \(errorDetails)"
Comment thread
ovitrif marked this conversation as resolved.
}
}
if let appError = error as? AppError,
Expand Down
2 changes: 1 addition & 1 deletion Bitkit/Views/Wallets/Send/LnurlPayConfirm.swift
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ struct LnurlPayConfirm: View {

// Fetch the Lightning invoice from LNURL
let bolt11 = try await LnurlHelper.fetchLnurlInvoice(
callbackUrl: lnurlPayData.callback,
data: lnurlPayData,
amountMsats: amountMsats,
comment: comment.isEmpty ? nil : comment
)
Expand Down
2 changes: 1 addition & 1 deletion Bitkit/Views/Wallets/Send/SendQuickpay.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct SendQuickpay: View {
wallet.sendAmountSats = lnurlPayData.minSendableSat

bolt11Invoice = try await LnurlHelper.fetchLnurlInvoice(
callbackUrl: lnurlPayData.callback,
data: lnurlPayData,
amountMsats: lnurlPayData.callbackAmountMsats()
)
} else if let scannedInvoice = app.scannedLightningInvoice {
Expand Down
1 change: 1 addition & 0 deletions changelog.d/hotfix/607.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Improved LNURL-pay invoice validation.
Loading