diff --git a/src/nwc_keysend.rs b/src/nwc_keysend.rs index c53c88d..1ef56f3 100644 --- a/src/nwc_keysend.rs +++ b/src/nwc_keysend.rs @@ -11,7 +11,6 @@ use nostr::nips::nip47::{self}; use crate::{ structs::{NwcStore, PluginState}, util::{ - at_or_above_version, budget_amount_check, get_budget_msat, load_nwc_store, @@ -20,6 +19,8 @@ use crate::{ }, }; +pub const XKEYSEND_COMMAND: &str = "xkeysend"; + pub async fn pay_keysend_response( plugin: Plugin, params: nip47::PayKeysendRequest, @@ -84,12 +85,7 @@ async fn pay_keysend( message: e.to_string(), })?; - let my_cln_version = plugin.state().config.lock().my_cln_version.clone(); - - if at_or_above_version(&my_cln_version, "26.06").map_err(|e| nip47::NIP47Error { - code: nip47::ErrorCode::Other, - message: e.to_string(), - })? { + if plugin.state().config.lock().has_xkeysend { xkeysend(&mut rpc, params, pubkey, nwc_store, label).await } else { keysend(&mut rpc, params, pubkey, nwc_store, label).await diff --git a/src/nwc_pay.rs b/src/nwc_pay.rs index d41210b..ffc348a 100644 --- a/src/nwc_pay.rs +++ b/src/nwc_pay.rs @@ -13,7 +13,6 @@ use nostr::nips::nip47; use crate::{ structs::{NOT_INV_ERR, NwcStore, PluginState}, util::{ - at_or_above_version, budget_amount_check, get_budget_msat, load_nwc_store, @@ -22,6 +21,8 @@ use crate::{ }, }; +pub const XPAY_COMMAND: &str = "xpay"; + pub async fn pay_invoice_response( plugin: Plugin, params: nip47::PayInvoiceRequest, @@ -63,10 +64,7 @@ async fn pay_invoice( let nwc_store = load_nwc_and_check_budget(&mut rpc, label, ¶ms, invoice_amt_msat, &id).await?; - let my_version = plugin.state().config.lock().clone().my_cln_version; - let use_xpay = check_cln_version(&my_version, &id)?; - - if use_xpay { + if plugin.state().config.lock().has_xpay { pay_with_xpay_full(&mut rpc, params, label, nwc_store, &id).await } else { pay_with_legacy_full(&mut rpc, params, label, nwc_store, &id).await @@ -197,21 +195,6 @@ async fn load_nwc_and_check_budget( Ok(nwc_store) } -fn check_cln_version( - my_version: &str, - id: &str, -) -> Result)> { - at_or_above_version(my_version, "24.11").map_err(|e| { - ( - nip47::NIP47Error { - code: nip47::ErrorCode::Internal, - message: e.to_string(), - }, - Some(id.to_owned()), - ) - }) -} - async fn update_budget_and_create_response( rpc: &mut ClnRpc, label: &str, diff --git a/src/parse.rs b/src/parse.rs index efd1e36..1589944 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,12 +1,14 @@ -use std::path::Path; +use std::{collections::HashSet, path::Path}; use anyhow::anyhow; use cln_plugin::ConfiguredPlugin; -use cln_rpc::{ClnRpc, model::requests::GetinfoRequest}; +use cln_rpc::{ClnRpc, model::requests::HelpRequest}; use nostr::types::RelayUrl; use crate::{ OPT_RELAYS, + nwc_keysend::XKEYSEND_COMMAND, + nwc_pay::XPAY_COMMAND, structs::{PluginState, TimeUnit}, }; @@ -33,9 +35,34 @@ pub async fn read_startup_options( Path::new(&plugin.configuration().lightning_dir).join(&plugin.configuration().rpc_file), ) .await?; - let version = rpc.call_typed(&GetinfoRequest {}).await?.version; + let help = rpc.call_typed(&HelpRequest { command: None }).await?; + let mut config = state.config.lock(); - config.my_cln_version = version; + + let mut available_commands = HashSet::new(); + for command in &help.help { + if let Some(method) = command.command.split_ascii_whitespace().next() { + available_commands.insert(method); + } + } + + log::debug!( + "Found {} commands available: {}", + available_commands.len(), + available_commands + .iter() + .copied() + .collect::>() + .join(" ") + ); + + config.has_xkeysend = available_commands.contains(XKEYSEND_COMMAND); + config.has_xpay = available_commands.contains(XPAY_COMMAND); + log::debug!( + "Using xpay:{} xkeysend:{}", + config.has_xpay, + config.has_xkeysend + ); for relay in relays_str { log::debug!("RELAY:{relay}"); config.relays.push(RelayUrl::parse(&relay)?); diff --git a/src/structs.rs b/src/structs.rs index 6018153..1ebfb85 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -1,4 +1,9 @@ -use std::{collections::HashMap, path::PathBuf, str::FromStr, sync::Arc}; +use std::{ + collections::{HashMap, HashSet}, + path::PathBuf, + str::FromStr, + sync::Arc, +}; use cln_rpc::ClnRpc; use nostr::{ @@ -44,13 +49,15 @@ pub struct WalletService { #[derive(Clone, Debug)] pub struct Config { pub relays: Vec, - pub my_cln_version: String, + pub has_xkeysend: bool, + pub has_xpay: bool, } impl Config { pub fn default() -> Config { Config { relays: Vec::new(), - my_cln_version: String::new(), + has_xkeysend: false, + has_xpay: false, } } } diff --git a/src/util.rs b/src/util.rs index 2012e6c..20fa53f 100644 --- a/src/util.rs +++ b/src/util.rs @@ -154,34 +154,6 @@ pub async fn save_event_id( Ok(()) } -pub fn at_or_above_version(my_version: &str, min_version: &str) -> Result { - let clean_start_my_version = my_version - .split_once('v') - .ok_or_else(|| anyhow!("Could not find v in version string"))? - .1; - let full_clean_my_version: String = clean_start_my_version - .chars() - .take_while(|x| x.is_ascii_digit() || *x == '.') - .collect(); - - let my_version_parts: Vec<&str> = full_clean_my_version.split('.').collect(); - let min_version_parts: Vec<&str> = min_version.split('.').collect(); - - if my_version_parts.len() <= 1 || my_version_parts.len() > 3 { - return Err(anyhow!("Version string parse error: {my_version}")); - } - for (my, min) in my_version_parts.iter().zip(min_version_parts.iter()) { - let my_num: u32 = my.parse()?; - let min_num: u32 = min.parse()?; - - if my_num != min_num { - return Ok(my_num > min_num); - } - } - - Ok(my_version_parts.len() >= min_version_parts.len()) -} - pub fn build_capabilities(is_read_only: bool, plugin: &Plugin) -> (String, String) { let holdinvoice_support = plugin.state().hold_client.lock().is_some();