lwk_boltz 0.14.0

Liquid Wallet Kit - Boltz integration
Documentation
use std::{fmt::Display, str::FromStr};

use boltz_client::{lightning_invoice::ParseOrSemanticError, Bolt11Invoice};
use lightning::offers::{offer::Offer, parse::Bolt12ParseError};
use lnurl::lnurl::LnUrl;

#[derive(Debug)]
pub enum LightningPayment {
    Bolt11(Box<Bolt11Invoice>),
    Bolt12(Box<Offer>),
    LnUrl(Box<LnUrl>),
}

impl FromStr for LightningPayment {
    type Err = (ParseOrSemanticError, Bolt12ParseError, lnurl::Error);

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match Bolt11Invoice::from_str(s) {
            Ok(invoice) => Ok(LightningPayment::Bolt11(Box::new(invoice))),
            Err(e1) => match Offer::from_str(s) {
                Ok(offer) => Ok(LightningPayment::Bolt12(Box::new(offer))),
                Err(e2) => match LnUrl::from_str(s) {
                    Ok(lnurl) => Ok(LightningPayment::LnUrl(Box::new(lnurl))),
                    Err(e3) => Err((e1, e2, e3)),
                },
            },
        }
    }
}

impl Display for LightningPayment {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            LightningPayment::Bolt11(invoice) => write!(f, "{invoice}"),
            LightningPayment::Bolt12(offer) => write!(f, "{offer}"),
            LightningPayment::LnUrl(lnurl) => write!(f, "{lnurl}"),
        }
    }
}

impl From<Bolt11Invoice> for LightningPayment {
    fn from(invoice: Bolt11Invoice) -> Self {
        LightningPayment::Bolt11(Box::new(invoice))
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_from_str() {
        let invoice = "lnbc23230n1p5sxxunsp5tep5yrw63cy3tk74j3hpzqzhhzwe806wk0apjfsfn5x9wmpkzkdspp5z4f40v2whks0aj3kx4zuwrrem094pna4ehutev2p63djtff02a2sdquf35kw6r5de5kueeqwpshjmt9de6qxqyp2xqcqzxrrzjqf6rgswuygn5qr0p5dt2mvklrrcz6yy8pnzqr3eq962tqwprpfrzkzzxeyqq28qqqqqqqqqqqqqqq9gq2yrzjqtnpp8ds33zeg5a6cumptreev23g7pwlp39cvcz8jeuurayvrmvdsrw9ysqqq9gqqqqqqqqpqqqqq9sq2g9qyysgqqufsg7s6qcmfmjxvkf0ulupufr0yfqeajnv3mvtyqzz2rfwre2796rnkzsw44lw3nja5frg4w4m59xqlwwu774h4f79ysm05uugckugqdf84yl";
        let offer = "lno1zcss9sy46p548rukhu2vt7g0dsy9r00n2jswepsrngjt7w988ac94hpv";
        let lnurl =
            "lnurl1dp68gurn8ghj7mn0wd68yene9e3k7mf0d3h82unvwqhkzurf9amrztmvde6hymp0xge7pp36";
        let payment = LightningPayment::from_str(invoice).unwrap();
        assert!(matches!(payment, LightningPayment::Bolt11(_)));
        assert_eq!(payment.to_string(), invoice);
        let payment = LightningPayment::from_str(offer).unwrap();
        assert!(matches!(payment, LightningPayment::Bolt12(_)));
        assert_eq!(payment.to_string(), offer);
        let payment = LightningPayment::from_str(lnurl).unwrap();
        assert!(matches!(payment, LightningPayment::LnUrl(_)));
        assert_eq!(payment.to_string(), lnurl);
        let err = "not a valid invoice or offer or lnurl";
        let err = LightningPayment::from_str(err).unwrap_err();
        assert!(matches!(err, (_, _, _)));
    }
}