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 */