diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index d54fa2f..1c599b1 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -19,4 +19,4 @@ jobs: - name: Build run: cargo build --verbose - name: Run tests - run: cargo test --verbose + run: cargo test --all-features --verbose diff --git a/waila/Cargo.toml b/waila/Cargo.toml index c034598..6cb3f52 100644 --- a/waila/Cargo.toml +++ b/waila/Cargo.toml @@ -21,12 +21,15 @@ nostr = { version = "0.22.0-bitcoin-v0.29", default-features = false, features = lnurl-rs = { version = "=0.2.4", default-features = false } lightning-invoice = { version = "=0.23.0", default-features = false } lightning = { version = "0.0.115", default-features = false } +rgb-std = { version = "0.10.4", optional = true } +rgb-wallet = { version = "0.10.4", optional = true } wasm-bindgen = { version = "0.2", optional = true } [features] default = ["std"] std = ["bitcoin/std", "lightning-invoice/std", "lightning/std"] no-std = ["bitcoin/no-std", "lightning-invoice/no-std", "lightning/no-std"] +rgb = ["rgb-std", "rgb-wallet"] [package.metadata.wasm-pack.profile.release] wasm-opt = true diff --git a/waila/src/lib.rs b/waila/src/lib.rs index 9645352..d7b753e 100644 --- a/waila/src/lib.rs +++ b/waila/src/lib.rs @@ -9,6 +9,10 @@ use lightning_invoice::{Invoice, InvoiceDescription}; use lnurl::lightning_address::LightningAddress; use lnurl::lnurl::LnUrl; use nostr::prelude::*; +#[cfg(feature = "rgb")] +use rgbstd::Chain; +#[cfg(feature = "rgb")] +use rgbwallet::RgbInvoice; use crate::bip21::UnifiedUri; @@ -24,6 +28,13 @@ pub enum PaymentParams<'a> { LnUrl(LnUrl), LightningAddress(LightningAddress), Nostr(XOnlyPublicKey), + #[cfg(feature = "rgb")] + Rgb(RgbInvoice), +} + +#[cfg(feature = "rgb")] +fn map_chain_to_network(chain: Chain) -> Option { + Network::from_str(&chain.to_string()).ok() } impl PaymentParams<'_> { @@ -44,6 +55,8 @@ impl PaymentParams<'_> { PaymentParams::LnUrl(_) => None, PaymentParams::LightningAddress(_) => None, PaymentParams::Nostr(_) => None, + #[cfg(feature = "rgb")] + PaymentParams::Rgb(_) => None, } } @@ -57,6 +70,8 @@ impl PaymentParams<'_> { PaymentParams::LnUrl(_) => None, PaymentParams::LightningAddress(_) => None, PaymentParams::Nostr(_) => None, + #[cfg(feature = "rgb")] + PaymentParams::Rgb(invoice) => invoice.chain.and_then(map_chain_to_network), } } @@ -72,6 +87,11 @@ impl PaymentParams<'_> { PaymentParams::LnUrl(_) => None, PaymentParams::LightningAddress(_) => None, PaymentParams::Nostr(_) => None, + #[cfg(feature = "rgb")] + PaymentParams::Rgb(invoice) => invoice + .chain + .and_then(map_chain_to_network) + .map(|n| n == network), } } @@ -93,6 +113,8 @@ impl PaymentParams<'_> { PaymentParams::LnUrl(_) => None, PaymentParams::LightningAddress(_) => None, PaymentParams::Nostr(_) => None, + #[cfg(feature = "rgb")] + PaymentParams::Rgb(_) => None, } } @@ -106,6 +128,8 @@ impl PaymentParams<'_> { PaymentParams::LnUrl(_) => None, PaymentParams::LightningAddress(_) => None, PaymentParams::Nostr(_) => None, + #[cfg(feature = "rgb")] + PaymentParams::Rgb(_) => None, } } @@ -119,6 +143,8 @@ impl PaymentParams<'_> { PaymentParams::LnUrl(_) => None, PaymentParams::LightningAddress(_) => None, PaymentParams::Nostr(_) => None, + #[cfg(feature = "rgb")] + PaymentParams::Rgb(_) => None, } } @@ -136,6 +162,8 @@ impl PaymentParams<'_> { PaymentParams::LnUrl(_) => None, PaymentParams::LightningAddress(_) => None, PaymentParams::Nostr(_) => None, + #[cfg(feature = "rgb")] + PaymentParams::Rgb(_) => None, } } @@ -149,6 +177,8 @@ impl PaymentParams<'_> { PaymentParams::LnUrl(lnurl) => Some(lnurl.clone()), PaymentParams::LightningAddress(ln_addr) => Some(LnUrl::from_url(ln_addr.lnurlp_url())), PaymentParams::Nostr(_) => None, + #[cfg(feature = "rgb")] + PaymentParams::Rgb(_) => None, } } @@ -168,6 +198,8 @@ impl PaymentParams<'_> { PaymentParams::LnUrl(_) => None, PaymentParams::LightningAddress(ln_addr) => Some(ln_addr.clone()), PaymentParams::Nostr(_) => None, + #[cfg(feature = "rgb")] + PaymentParams::Rgb(_) => None, } } @@ -181,6 +213,8 @@ impl PaymentParams<'_> { PaymentParams::LnUrl(_) => None, PaymentParams::LightningAddress(_) => None, PaymentParams::Nostr(key) => Some(*key), + #[cfg(feature = "rgb")] + PaymentParams::Rgb(_) => None, } } } @@ -218,6 +252,13 @@ impl FromStr for PaymentParams<'_> { .map_err(|_| ()); } + #[cfg(feature = "rgb")] + if lower.starts_with("rgb:") { + return RgbInvoice::from_str(str) + .map(PaymentParams::Rgb) + .map_err(|_| ()); + } + Address::from_str(str) .map(PaymentParams::OnChain) .or_else(|_| Invoice::from_str(str).map(PaymentParams::Bolt11)) @@ -245,6 +286,7 @@ mod tests { const SAMPLE_BIP21_WITH_INVOICE: &str = "bitcoin:BC1QYLH3U67J673H6Y6ALV70M0PL2YZ53TZHVXGG7U?amount=0.00001&label=sbddesign%3A%20For%20lunch%20Tuesday&message=For%20lunch%20Tuesday&lightning=LNBC10U1P3PJ257PP5YZTKWJCZ5FTL5LAXKAV23ZMZEKAW37ZK6KMV80PK4XAEV5QHTZ7QDPDWD3XGER9WD5KWM36YPRX7U3QD36KUCMGYP282ETNV3SHJCQZPGXQYZ5VQSP5USYC4LK9CHSFP53KVCNVQ456GANH60D89REYKDNGSMTJ6YW3NHVQ9QYYSSQJCEWM5CJWZ4A6RFJX77C490YCED6PEMK0UPKXHY89CMM7SCT66K8GNEANWYKZGDRWRFJE69H9U5U0W57RRCSYSAS7GADWMZXC8C6T0SPJAZUP6"; const SAMPLE_BIP21_WITH_INVOICE_AND_LABEL: &str = "bitcoin:tb1p0vztr8q25czuka5u4ta5pqu0h8dxkf72mam89cpg4tg40fm8wgmqp3gv99?amount=0.000001&label=yooo&lightning=lntbs1u1pjrww6fdq809hk7mcnp4qvwggxr0fsueyrcer4x075walsv93vqvn3vlg9etesx287x6ddy4xpp5a3drwdx2fmkkgmuenpvmynnl7uf09jmgvtlg86ckkvgn99ajqgtssp5gr3aghgjxlwshnqwqn39c2cz5hw4cnsnzxdjn7kywl40rru4mjdq9qyysgqcqpcxqrpwurzjqfgtsj42x8an5zujpxvfhp9ngwm7u5lu8lvzfucjhex4pq8ysj5q2qqqqyqqv9cqqsqqqqlgqqqqqqqqfqzgl9zq04nzpxyvdr8vj3h98gvnj3luanj2cxcra0q2th4xjsxmtj8k3582l67xq9ffz5586f3nm5ax58xaqjg6rjcj2vzvx2q39v9eqpn0wx54"; const SAMPLE_LNURL: &str = "LNURL1DP68GURN8GHJ7UM9WFMXJCM99E3K7MF0V9CXJ0M385EKVCENXC6R2C35XVUKXEFCV5MKVV34X5EKZD3EV56NYD3HXQURZEPEXEJXXEPNXSCRVWFNV9NXZCN9XQ6XYEFHVGCXXCMYXYMNSERXFQ5FNS"; + const SAMPLE_RGB_INVOICE: &str = "rgb:Cbw1h3zbHgRhA6sxb4FS3Z7GTpdj9MLb7Do88qh5TUH1/RGB20/1+utxob0KPoUVTWL3WqyY6zsJY5giaugWHt5n4hEeWMQymQJmPRFPXL2n"; #[test] fn parse_node_pubkey() { @@ -508,4 +550,17 @@ mod tests { ) ); } + + #[test] + fn parse_rgb_invoice() { + let parsed = PaymentParams::from_str(SAMPLE_RGB_INVOICE).unwrap(); + + assert_eq!(parsed.amount(), None); + assert_eq!(parsed.address(), None); + assert_eq!(parsed.memo(), None); + assert_eq!(parsed.network(), None); + assert_eq!(parsed.invoice(), None); + assert_eq!(parsed.node_pubkey(), None); + assert_eq!(parsed.nostr_pubkey(), None); + } }