lnlink

iOS app for connecting to lightning nodes
git clone git://jb55.com/lnlink
Log | Files | Refs | Submodules | README | LICENSE

Invoice.swift (2597B)


      1 //
      2 //  Invoice.swift
      3 //  lightninglink
      4 //
      5 //  Created by William Casarin on 2022-02-05.
      6 //
      7 
      8 import Foundation
      9 
     10 
     11 public enum DecodeType {
     12     case offer(String)
     13     case invoice(InvoiceAmount, String)
     14     case lnurl(URL)
     15 }
     16 
     17 public enum InvoiceAmount {
     18     case amount(Int64)
     19     case min(Int64)
     20     case range(Int64, Int64)
     21     case any
     22 }
     23 
     24 // this is just a quick stopgap before we have full invoice parsing
     25 public func parseInvoiceString(_ invoice: String) -> DecodeType?
     26 {
     27     let inv = invoice.lowercased()
     28 
     29     if inv.starts(with: "lno1") {
     30         return .offer(inv)
     31     }
     32 
     33     let is_bolt11 = inv.starts(with: "lnbc")
     34     let is_bolt12 = inv.starts(with: "lni")
     35     if !(is_bolt11 || is_bolt12) {
     36         return nil
     37     }
     38 
     39     var ind = is_bolt11 ? 4 : 3
     40     var num: String = ""
     41     var scale: Character = Character("p")
     42     var sep: Character
     43 
     44     // number part
     45     while true {
     46         let c = inv[inv.index(inv.startIndex, offsetBy: ind)]
     47         ind += 1
     48 
     49         if c >= "0" && c <= "9" {
     50             continue
     51         } else {
     52             let start_ind = inv.index(inv.startIndex, offsetBy: 4)
     53             let end_ind = inv.index(inv.startIndex, offsetBy: ind - 1)
     54 
     55             scale = inv[inv.index(inv.startIndex, offsetBy: ind - 1)]
     56             sep = inv[inv.index(inv.startIndex, offsetBy: ind)]
     57             num = String(inv[start_ind..<end_ind])
     58 
     59             if sep != "1" {
     60                 return .invoice(.any, inv)
     61             }
     62 
     63             break
     64         }
     65     }
     66 
     67     if !(scale == "m" || scale == "u" || scale == "n" || scale == "p") {
     68         return nil
     69     }
     70 
     71     guard let n = Int(num) else {
     72         return nil
     73     }
     74 
     75     switch scale {
     76     case "m": return .invoice(.amount(Int64(n * 100000000)), inv);
     77     case "u": return .invoice(.amount(Int64(n * 100000)), inv);
     78     case "n": return .invoice(.amount(Int64(n * 100)), inv);
     79     case "p": return .invoice(.amount(Int64(n * 1)), inv);
     80     default: return nil
     81     }
     82 }
     83 
     84 public func lnurl_decode(_ str: String) {
     85 }
     86 
     87 /*
     88 public func parseInvoice(_ str: String) -> Invoice?
     89 {
     90     // decode bech32
     91 
     92     do {
     93         let (hrp, _) = try decodeBech32(bechString: str)
     94 
     95         let hrp_data = Data(hrp)
     96         let hrp_str = String(data: hrp_data, encoding: .utf8)!
     97         print(hrp_str)
     98 
     99     } catch {
    100         print("parseInvoice: unexpected error \(error)")
    101         return nil
    102     }
    103 
    104     return .bolt11(Bolt11Invoice(msats: 100000))
    105 }
    106 
    107 
    108 public func invoiceAmount(_ inv: Invoice) -> Int64
    109 {
    110     switch (inv) {
    111     case .bolt11(let b11):
    112         return b11.msats
    113     case .bolt12(let b12):
    114         return b12.msats
    115     }
    116 
    117 }
    118  */