I can send an LNURL withdrawal request using a deep link directly to Muun using something like the following "lightning:LNURL123...123". However anyone with more than one lightning wallet on iOS finds it impossible to have the URI open the correct wallet since iOS just opens the last wallet installed which supports the "lightning:" url scheme.
I can open Muun directly if I use "muun:LNURL123...123", however it doesn't process the invoice.
I think I've managed to follow the flow through your app and found that it just supports "lightning:"...
in AppDelegate.swift, the class AddressHelper tries to parse the URI:
// Deep/Universal links
func application(_ application: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:] ) -> Bool {
...
do {
let paymentIntent = try AddressHelper.parse(url.absoluteString)
...
}
}
Looking in AddressHelper.swift it'll hit parse(lnurl: raw), and then use the LibWallet Go code to try and validate:
// AddressHelper.swift
public enum AddressHelper {
static let muunScheme = "muun:"
static let bitcoinScheme = "bitcoin:"
public static func parse(_ raw: String) throws -> PaymentIntent {
if let address = try? parse(rawAddress: raw) {
return address
}
if let invoice = try? parse(rawInvoice: raw) {
return invoice
}
if let lnurl = parse(lnurl: raw) {
return lnurl
}
throw MuunError(ParseError.addressError)
}
static func parse(lnurl: String) -> PaymentIntent? {
if LibwalletLNURLValidate(lnurl) {
return .lnurlWithdraw(lnurl: lnurl)
}
return nil
}
}
In LibWallet, lnurl.go:
func LNURLValidate(qr string) bool {
return lnurl.Validate(qr)
}
Leading to the final validate and decode in lnurl.go:
func Validate(qr string) bool {
_, err := decode(qr)
return err == nil
}
func decode(qr string) (*url.URL, error) {
// handle fallback scheme
if strings.HasPrefix(qr, "http://") || strings.HasPrefix(qr, "https://") {
u, err := url.Parse(qr)
if err != nil {
return nil, err
}
qr = u.Query().Get("lightning")
} else {
// remove lightning prefix
if strings.HasPrefix(strings.ToLower(qr), "lightning:") {
qr = qr[len("lightning:"):]
}
}
u, err := lnurl.LNURLDecode(qr)
if err != nil {
return nil, err
}
return url.Parse(string(u))
}
So here I can see that this only works by removing the "lightning:" prefix, leaving the "LNURL123...123" invoice to decode.
Other wallets like BlueWallet work by allowing "bluewallet:lightning:LNURL123...123", or in the case of Wallet of Satoshi, just allowing "walletofsatoshi:LNURL123...123".
Would it be possible to allow either the "muun:" or "muun:lightning:" scheme to decode and process the invoice, so I can open Muun directly? This would allow us at THNDR Games to add support for Muun wallet for our sats prize payments on iOS.
I think one solution could literally be to add an else clause to the above, but I don't know the codebase well enough to know if this is the only place "lightning" is used
else if strings.HasPrefix(strings.ToLower(qr), "muun:lightning:") {
qr = qr[len("muun:lightning:"):]
}
As an aside, "muun:LNURL123...123" works fine with Muun on Android, so I don't know how the Apollo project version does it?
Thanks!