Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

feature: detect clipboard for lightning invoice #331

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
21 changes: 21 additions & 0 deletions Library/Coordinators/WalletCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,30 @@ final class WalletCoordinator: NSObject, Coordinator {
}

self.currentState = state
if self.currentState == .syncing || self.currentState == .running {
detectPasteboardForLightningInvoice()
}

UIApplication.shared.isIdleTimerDisabled = lightningService.connection == .local && state == .syncing
}

private func detectPasteboardForLightningInvoice() {
let pasteboard = UIPasteboard.general
guard let string = pasteboard.string else { return }
guard LightningInvoiceURI.validate(string: string) else { return }

let alertController = UIAlertController(title: L10n.Generic.Pasteboard.LightniningInvoiceFoundAlert.title,
message: L10n.Generic.Pasteboard.LightniningInvoiceFoundAlert.message,
preferredStyle: .actionSheet)
let cancelAlertAction = UIAlertAction(title: L10n.Generic.cancel, style: .cancel, handler: nil)
let sendPaymentAction = UIAlertAction(title: L10n.Generic.Pasteboard.LightniningInvoiceFoundAlert.send,
style: .default) { _ in
self.presentSend(invoice: string)
}
alertController.addAction(cancelAlertAction)
alertController.addAction(sendPaymentAction)
(detailViewController ?? rootViewController).present(alertController, animated: true)
}

private func presentUnlockWallet() {
guard
Expand Down
8 changes: 8 additions & 0 deletions Library/Generated/strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ internal enum L10n {
internal enum Pasteboard {
/// Invalid Address
internal static let invalidAddress = L10n.tr("Localizable", "generic.pasteboard.invalid_address")
internal enum LightniningInvoiceFoundAlert {
/// Would you like to send a payment for the invoice?
internal static let message = L10n.tr("Localizable", "generic.pasteboard.lightnining_invoice_found_alert.message")
/// Send
internal static let send = L10n.tr("Localizable", "generic.pasteboard.lightnining_invoice_found_alert.send")
/// Lightning Invoice found on clipboard
internal static let title = L10n.tr("Localizable", "generic.pasteboard.lightnining_invoice_found_alert.title")
}
}
internal enum QrCode {
/// Copy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ final class WalletConfigurationStore {
return configurations.isEmpty
}
private(set) var configurations: [WalletConfiguration]
var selectedWallet: WalletConfiguration? { // make lighting connection
var selectedWallet: WalletConfiguration? { // make lightning connection
didSet {
save()
}
Expand Down
3 changes: 3 additions & 0 deletions Library/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
"generic.qr_code.copy_button" = "Copy";
"generic.qr_code.copy_success_message" = "Address has been copied to clipboard.";
"generic.pasteboard.invalid_address" = "Invalid Address";
"generic.pasteboard.lightnining_invoice_found_alert.send" = "Send";
"generic.pasteboard.lightnining_invoice_found_alert.title" = "Lightning Invoice found on clipboard";
"generic.pasteboard.lightnining_invoice_found_alert.message" = "Would you like to send a payment for the invoice?";
"generic.qr_code.share_button" = "Share";
"generic.cancel" = "Cancel";

Expand Down
24 changes: 16 additions & 8 deletions Lightning/Invoice/LightningInvoiceURI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,14 @@ public struct LightningInvoiceURI: PaymentURI {
public let address: String
public let network: Network
public var isCaseSensitive = false
private static let lightningPrefix = "lightning:"

public var uriString: String {
return "lightning:\(address)"
}

public init?(string: String) {
var string = string.lowercased()

let prefix = "lightning:"
if string.starts(with: prefix) {
string = String(string.dropFirst(prefix.count))
}

guard let invoice = Bolt11.decode(string: string) else { return nil }
guard let invoice = LightningInvoiceURI.decode(string: string) else { return nil }

address = string
amount = invoice.amount
Expand All @@ -39,4 +33,18 @@ public struct LightningInvoiceURI: PaymentURI {
public init?(invoice: Invoice) {
self.init(string: invoice.paymentRequest)
}

public static func validate(string: String) -> Bool {
return decode(string: string) != nil
}

private static func decode(string: String) -> Bolt11.Invoice? {
var string = string.lowercased()

if string.starts(with: lightningPrefix) {
string = String(string.dropFirst(lightningPrefix.count))
}

return Bolt11.decode(string: string)
}
}