Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
248339c
fix: add expiry check for BIP 21 invoices
jvsena42 Jan 12, 2026
10fb650
fix: add expiry check for pure lightning invoices
jvsena42 Jan 12, 2026
2c1ea1c
fix: check if invoice expired while user was on confirmation screen
jvsena42 Jan 12, 2026
886a465
fix: replace info type with error
jvsena42 Jan 12, 2026
6cb9029
fix: handle route for null onchain invoice and expired ln bolt 11
jvsena42 Jan 12, 2026
8beb29a
refactor: simplify logic
jvsena42 Jan 12, 2026
b3b22a4
refactor: replace nil check with let
jvsena42 Jan 12, 2026
c38e815
Merge branch 'master' into fix/fallback-expired-ln-to-onchain
jvsena42 Jan 12, 2026
92d36e3
Merge branch 'master' into fix/fallback-expired-ln-to-onchain
jvsena42 Jan 13, 2026
970e3fb
Merge branch 'master' into fix/fallback-expired-ln-to-onchain
ovitrif Jan 13, 2026
c40fa49
Merge branch 'master' into fix/fallback-expired-ln-to-onchain
ovitrif Jan 13, 2026
8faa97e
Merge branch 'master' into fix/fallback-expired-ln-to-onchain
jvsena42 Jan 13, 2026
af4cc26
Merge branch 'master' into fix/fallback-expired-ln-to-onchain
jvsena42 Jan 13, 2026
4a563fc
fix: prioritize insufficient funds error
jvsena42 Jan 14, 2026
0a0f009
Merge branch 'fix/fallback-expired-ln-to-onchain' of github.com:synon…
jvsena42 Jan 14, 2026
23b0094
fix: prioritize insufficient funds error
jvsena42 Jan 14, 2026
21777f7
fix: lightning only error message
jvsena42 Jan 14, 2026
a880401
fix: add specific error cases and debounce
jvsena42 Jan 14, 2026
ea64332
fix: stale input validation
jvsena42 Jan 14, 2026
e3e269c
fix: disable autocapitalization and autocorrect
jvsena42 Jan 14, 2026
daa26e0
fix: add network validation
jvsena42 Jan 14, 2026
e9812c8
fix: lightning balance error
jvsena42 Jan 14, 2026
65627fa
fix: onchain balance validation for pasting option
jvsena42 Jan 14, 2026
9a054b1
refactor: extract network validation
jvsena42 Jan 14, 2026
b584a10
refactor: remove useless expired validation
jvsena42 Jan 14, 2026
f2d77bb
fix: string reference
jvsena42 Jan 14, 2026
4f45850
fix: stale sequence check
jvsena42 Jan 14, 2026
57ee828
fix: error toast description
jvsena42 Jan 14, 2026
977ecd2
fix(scan): improve toasts
pwltr Jan 14, 2026
89668a6
Merge branch 'master' into fix/fallback-expired-ln-to-onchain
jvsena42 Jan 15, 2026
19c6bad
Merge branch 'master' into fix/fallback-expired-ln-to-onchain
jvsena42 Jan 16, 2026
ff520f3
Merge branch 'master' into fix/fallback-expired-ln-to-onchain
jvsena42 Jan 16, 2026
1d0f261
Merge branch 'master' into fix/fallback-expired-ln-to-onchain
jvsena42 Jan 16, 2026
c4d30e1
add toast ids
piotr-iohk Jan 16, 2026
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
1 change: 1 addition & 0 deletions Bitkit/Resources/Localization/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@
"other__pay_insufficient_spending" = "Insufficient Spending Balance";
"other__pay_insufficient_savings_description" = "More ₿ needed to pay this Bitcoin invoice.";
"other__pay_insufficient_savings_amount_description" = "₿ {amount} more needed to pay this Bitcoin invoice.";
"other__pay_insufficient_spending_description" = "More ₿ needed to pay this Lightning invoice.";
"other__pay_insufficient_spending_amount_description" = "₿ {amount} more needed to pay this Lightning invoice.";
"other__swipe" = "Swipe To Confirm";
"other__scan_err_decoding" = "Decoding Error";
Expand Down
8 changes: 8 additions & 0 deletions Bitkit/Utilities/CurrencyFormatter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,12 @@ enum CurrencyFormatter {

return formatter.string(from: amount as NSDecimalNumber) ?? ""
}

/// Format satoshis with space as grouping separator (e.g., 10000 -> "10 000")
static func formatSats(_ sats: UInt64) -> String {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.groupingSeparator = " "
return formatter.string(from: NSNumber(value: sats)) ?? String(sats)
}
}
57 changes: 57 additions & 0 deletions Bitkit/Utilities/NetworkValidationHelper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import BitkitCore
import LDKNode

/// Helper for validating Bitcoin network compatibility of addresses and invoices
enum NetworkValidationHelper {
/// Infer the Bitcoin network from an on-chain address prefix
/// - Parameter address: The Bitcoin address to check
/// - Returns: The detected network, or nil if the address format is unrecognized
static func getAddressNetwork(_ address: String) -> LDKNode.Network? {
let lowercased = address.lowercased()

// Bech32/Bech32m addresses (order matters: check bcrt1 before bc1)
if lowercased.hasPrefix("bcrt1") {
return .regtest
} else if lowercased.hasPrefix("bc1") {
return .bitcoin
} else if lowercased.hasPrefix("tb1") {
return .testnet
}

// Legacy addresses - check first character
guard let first = address.first else { return nil }
switch first {
case "1", "3": return .bitcoin
case "m", "n", "2": return .testnet // testnet and regtest share these
default: return nil
}
}

/// Convert BitkitCore.NetworkType to LDKNode.Network
/// - Parameter networkType: The BitkitCore network type
/// - Returns: The equivalent LDKNode network
static func convertNetworkType(_ networkType: NetworkType) -> LDKNode.Network {
switch networkType {
case .bitcoin: return .bitcoin
case .testnet: return .testnet
case .signet: return .signet
case .regtest: return .regtest
}
}

/// Check if an address/invoice network mismatches the current app network
/// - Parameters:
/// - addressNetwork: The network detected from the address/invoice
/// - currentNetwork: The app's current network (typically Env.network)
/// - Returns: true if there's a mismatch (address won't work on current network)
static func isNetworkMismatch(addressNetwork: LDKNode.Network?, currentNetwork: LDKNode.Network) -> Bool {
guard let addressNetwork else { return false }

// Special case: regtest uses testnet prefixes (m, n, 2, tb1)
if currentNetwork == .regtest && addressNetwork == .testnet {
return false
}

return addressNetwork != currentNetwork
}
}
13 changes: 9 additions & 4 deletions Bitkit/Utilities/PaymentNavigationHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ struct PaymentNavigationHelper {
app: AppViewModel,
currency: CurrencyViewModel,
settings: SettingsViewModel
) -> SendRoute {
) -> SendRoute? {
if let lnurlWithdrawData = app.lnurlWithdrawData {
if lnurlWithdrawData.minWithdrawable == lnurlWithdrawData.maxWithdrawable {
return .lnurlWithdrawConfirm
Expand All @@ -125,8 +125,8 @@ struct PaymentNavigationHelper {
}

// Handle lightning invoice
if app.scannedLightningInvoice != nil {
let amount = app.scannedLightningInvoice!.amountSatoshis
if let invoice = app.scannedLightningInvoice {
let amount = invoice.amountSatoshis

if amount > 0 && shouldUseQuickpay {
return .quickpay
Expand All @@ -140,6 +140,11 @@ struct PaymentNavigationHelper {
}

// Handle onchain invoice
return .amount
if let _ = app.scannedOnchainInvoice {
return .amount
}

// No valid invoice data
return nil
}
}
Loading
Loading