From c522b5cc3cc223bc87e0158cfe749129eac83844 Mon Sep 17 00:00:00 2001 From: Ovi Trif Date: Fri, 26 Jun 2026 05:04:59 +0200 Subject: [PATCH 1/4] fix: use core LNURL-pay validation --- Bitkit.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/swiftpm/Package.resolved | 4 +- Bitkit/Utilities/Lnurl.swift | 50 +++++++++++-------- .../ViewModels/Trezor/TrezorViewModel.swift | 2 + .../Views/Wallets/Send/LnurlPayConfirm.swift | 2 +- Bitkit/Views/Wallets/Send/SendQuickpay.swift | 2 +- changelog.d/hotfix/607.fixed.md | 1 + 7 files changed, 36 insertions(+), 27 deletions(-) create mode 100644 changelog.d/hotfix/607.fixed.md diff --git a/Bitkit.xcodeproj/project.pbxproj b/Bitkit.xcodeproj/project.pbxproj index 9519ceb31..da49763f5 100644 --- a/Bitkit.xcodeproj/project.pbxproj +++ b/Bitkit.xcodeproj/project.pbxproj @@ -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" */ = { diff --git a/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 1347ccc14..da128ae92 100644 --- a/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -6,8 +6,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/synonymdev/bitkit-core", "state" : { - "revision" : "a7577cc4572d581a0ab1d84f2792a1e6198110ef", - "version" : "0.1.64" + "revision" : "201e37b1951d9ec68e7c46d2534314afe5ccac3c", + "version" : "0.1.74" } }, { diff --git a/Bitkit/Utilities/Lnurl.swift b/Bitkit/Utilities/Lnurl.swift index bdff50594..bf8a1598a 100644 --- a/Bitkit/Utilities/Lnurl.swift +++ b/Bitkit/Utilities/Lnurl.swift @@ -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? @@ -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 diff --git a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift index 3f47ea5bb..832f70b11 100644 --- a/Bitkit/ViewModels/Trezor/TrezorViewModel.swift +++ b/Bitkit/ViewModels/Trezor/TrezorViewModel.swift @@ -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)" } } if let appError = error as? AppError, diff --git a/Bitkit/Views/Wallets/Send/LnurlPayConfirm.swift b/Bitkit/Views/Wallets/Send/LnurlPayConfirm.swift index 2161ed0da..727a200b2 100644 --- a/Bitkit/Views/Wallets/Send/LnurlPayConfirm.swift +++ b/Bitkit/Views/Wallets/Send/LnurlPayConfirm.swift @@ -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 ) diff --git a/Bitkit/Views/Wallets/Send/SendQuickpay.swift b/Bitkit/Views/Wallets/Send/SendQuickpay.swift index d6b5c78e0..361e98ed0 100644 --- a/Bitkit/Views/Wallets/Send/SendQuickpay.swift +++ b/Bitkit/Views/Wallets/Send/SendQuickpay.swift @@ -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 { diff --git a/changelog.d/hotfix/607.fixed.md b/changelog.d/hotfix/607.fixed.md new file mode 100644 index 000000000..3a4d4d29f --- /dev/null +++ b/changelog.d/hotfix/607.fixed.md @@ -0,0 +1 @@ +Improved LNURL-pay invoice validation. From d700f60075c569737cc87397a3c0195e2911251f Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Fri, 26 Jun 2026 13:52:06 +0200 Subject: [PATCH 2/4] chore: version 2.3.1 Co-authored-by: Cursor --- Bitkit.xcodeproj/project.pbxproj | 24 ++++++++++++------------ CHANGELOG.md | 8 +++++++- changelog.d/hotfix/607.fixed.md | 1 - 3 files changed, 19 insertions(+), 14 deletions(-) delete mode 100644 changelog.d/hotfix/607.fixed.md diff --git a/Bitkit.xcodeproj/project.pbxproj b/Bitkit.xcodeproj/project.pbxproj index da49763f5..bdf90e7ab 100644 --- a/Bitkit.xcodeproj/project.pbxproj +++ b/Bitkit.xcodeproj/project.pbxproj @@ -679,7 +679,7 @@ ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; CODE_SIGN_ENTITLEMENTS = BitkitWidgetExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 190; + CURRENT_PROJECT_VERSION = 191; DEVELOPMENT_TEAM = KYH47R284B; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = BitkitWidget/Info.plist; @@ -691,7 +691,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.0; + MARKETING_VERSION = 2.3.1; PRODUCT_BUNDLE_IDENTIFIER = to.bitkit.widget; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -712,7 +712,7 @@ ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; CODE_SIGN_ENTITLEMENTS = BitkitWidgetExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 190; + CURRENT_PROJECT_VERSION = 191; DEVELOPMENT_TEAM = KYH47R284B; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = BitkitWidget/Info.plist; @@ -724,7 +724,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.0; + MARKETING_VERSION = 2.3.1; PRODUCT_BUNDLE_IDENTIFIER = to.bitkit.widget; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; @@ -744,7 +744,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = BitkitNotification/BitkitNotification.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 190; + CURRENT_PROJECT_VERSION = 191; DEVELOPMENT_TEAM = KYH47R284B; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = BitkitNotification/Info.plist; @@ -756,7 +756,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.0; + MARKETING_VERSION = 2.3.1; OTHER_LDFLAGS = ( "-framework", CoreBluetooth, @@ -776,7 +776,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = BitkitNotification/BitkitNotification.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 190; + CURRENT_PROJECT_VERSION = 191; DEVELOPMENT_TEAM = KYH47R284B; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = BitkitNotification/Info.plist; @@ -788,7 +788,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 2.3.0; + MARKETING_VERSION = 2.3.1; OTHER_LDFLAGS = ( "-framework", CoreBluetooth, @@ -926,7 +926,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Bitkit/Bitkit.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 190; + CURRENT_PROJECT_VERSION = 191; DEVELOPMENT_ASSET_PATHS = "\"Bitkit/Preview Content\""; DEVELOPMENT_TEAM = KYH47R284B; ENABLE_HARDENED_RUNTIME = YES; @@ -953,7 +953,7 @@ LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 14.0; - MARKETING_VERSION = 2.3.0; + MARKETING_VERSION = 2.3.1; OTHER_LDFLAGS = ( "-framework", CoreBluetooth, @@ -975,7 +975,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Bitkit/Bitkit.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 190; + CURRENT_PROJECT_VERSION = 191; DEVELOPMENT_ASSET_PATHS = "\"Bitkit/Preview Content\""; DEVELOPMENT_TEAM = KYH47R284B; ENABLE_HARDENED_RUNTIME = YES; @@ -1002,7 +1002,7 @@ LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 14.0; - MARKETING_VERSION = 2.3.0; + MARKETING_VERSION = 2.3.1; OTHER_LDFLAGS = ( "-framework", CoreBluetooth, diff --git a/CHANGELOG.md b/CHANGELOG.md index 1261b8d0b..f500c9e88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [2.3.1] - 2026-06-26 + +### Fixed +- Improved LNURL-pay invoice validation. #607 + ## [2.3.0] - 2026-06-04 ### Added @@ -53,7 +58,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix keyboard and UI issues in the calculator widget #513 - Preserve msat precision for LNURL pay, withdraw callbacks and bolt11 #512 -[Unreleased]: https://github.com/synonymdev/bitkit-ios/compare/v2.3.0...HEAD +[Unreleased]: https://github.com/synonymdev/bitkit-ios/compare/v2.3.1...HEAD +[2.3.1]: https://github.com/synonymdev/bitkit-ios/compare/v2.3.0...v2.3.1 [2.3.0]: https://github.com/synonymdev/bitkit-ios/compare/v2.2.1...v2.3.0 [2.2.1]: https://github.com/synonymdev/bitkit-ios/compare/v2.2.0...v2.2.1 [2.2.0]: https://github.com/synonymdev/bitkit-ios/compare/v2.1.2...v2.2.0 diff --git a/changelog.d/hotfix/607.fixed.md b/changelog.d/hotfix/607.fixed.md deleted file mode 100644 index 3a4d4d29f..000000000 --- a/changelog.d/hotfix/607.fixed.md +++ /dev/null @@ -1 +0,0 @@ -Improved LNURL-pay invoice validation. From 9d1bd9b822c5581b632b2cabdd7354ae29ceb2a1 Mon Sep 17 00:00:00 2001 From: Ovi Trif Date: Fri, 26 Jun 2026 16:45:27 +0200 Subject: [PATCH 3/4] fix: update bitkit core --- Bitkit.xcodeproj/project.pbxproj | 2 +- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 4 ++-- changelog.d/hotfix/610.fixed.md | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 changelog.d/hotfix/610.fixed.md diff --git a/Bitkit.xcodeproj/project.pbxproj b/Bitkit.xcodeproj/project.pbxproj index bdf90e7ab..1ca93702d 100644 --- a/Bitkit.xcodeproj/project.pbxproj +++ b/Bitkit.xcodeproj/project.pbxproj @@ -1201,7 +1201,7 @@ repositoryURL = "https://github.com/synonymdev/bitkit-core"; requirement = { kind = exactVersion; - version = 0.1.74; + version = 0.1.75; }; }; 96E20CD22CB6D91A00C24149 /* XCRemoteSwiftPackageReference "CodeScanner" */ = { diff --git a/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index da128ae92..a1debc138 100644 --- a/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -6,8 +6,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/synonymdev/bitkit-core", "state" : { - "revision" : "201e37b1951d9ec68e7c46d2534314afe5ccac3c", - "version" : "0.1.74" + "revision" : "496c08423885b211300a973dad9675df5ecdbaa6", + "version" : "0.1.75" } }, { diff --git a/changelog.d/hotfix/610.fixed.md b/changelog.d/hotfix/610.fixed.md new file mode 100644 index 000000000..af216c389 --- /dev/null +++ b/changelog.d/hotfix/610.fixed.md @@ -0,0 +1 @@ +Improved LNURL-pay payment handling. From a7c462979c6c353b098efd80df71b0acad1dbf83 Mon Sep 17 00:00:00 2001 From: Piotr Stachyra Date: Fri, 26 Jun 2026 20:58:51 +0200 Subject: [PATCH 4/4] chore: build 192 Collect hotfix changelog for #610 and bump build for TestFlight upload. Co-authored-by: Cursor --- Bitkit.xcodeproj/project.pbxproj | 12 ++++++------ CHANGELOG.md | 1 + changelog.d/hotfix/610.fixed.md | 1 - 3 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 changelog.d/hotfix/610.fixed.md diff --git a/Bitkit.xcodeproj/project.pbxproj b/Bitkit.xcodeproj/project.pbxproj index 1ca93702d..2f873a92e 100644 --- a/Bitkit.xcodeproj/project.pbxproj +++ b/Bitkit.xcodeproj/project.pbxproj @@ -679,7 +679,7 @@ ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; CODE_SIGN_ENTITLEMENTS = BitkitWidgetExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 191; + CURRENT_PROJECT_VERSION = 192; DEVELOPMENT_TEAM = KYH47R284B; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = BitkitWidget/Info.plist; @@ -712,7 +712,7 @@ ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; CODE_SIGN_ENTITLEMENTS = BitkitWidgetExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 191; + CURRENT_PROJECT_VERSION = 192; DEVELOPMENT_TEAM = KYH47R284B; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = BitkitWidget/Info.plist; @@ -744,7 +744,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = BitkitNotification/BitkitNotification.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 191; + CURRENT_PROJECT_VERSION = 192; DEVELOPMENT_TEAM = KYH47R284B; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = BitkitNotification/Info.plist; @@ -776,7 +776,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = BitkitNotification/BitkitNotification.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 191; + CURRENT_PROJECT_VERSION = 192; DEVELOPMENT_TEAM = KYH47R284B; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = BitkitNotification/Info.plist; @@ -926,7 +926,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Bitkit/Bitkit.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 191; + CURRENT_PROJECT_VERSION = 192; DEVELOPMENT_ASSET_PATHS = "\"Bitkit/Preview Content\""; DEVELOPMENT_TEAM = KYH47R284B; ENABLE_HARDENED_RUNTIME = YES; @@ -975,7 +975,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = Bitkit/Bitkit.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 191; + CURRENT_PROJECT_VERSION = 192; DEVELOPMENT_ASSET_PATHS = "\"Bitkit/Preview Content\""; DEVELOPMENT_TEAM = KYH47R284B; ENABLE_HARDENED_RUNTIME = YES; diff --git a/CHANGELOG.md b/CHANGELOG.md index f500c9e88..de6a117c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Improved LNURL-pay invoice validation. #607 +- Improved LNURL-pay payment handling. #610 ## [2.3.0] - 2026-06-04 diff --git a/changelog.d/hotfix/610.fixed.md b/changelog.d/hotfix/610.fixed.md deleted file mode 100644 index af216c389..000000000 --- a/changelog.d/hotfix/610.fixed.md +++ /dev/null @@ -1 +0,0 @@ -Improved LNURL-pay payment handling.