determine available methods from help rpc isntead of version string

This commit is contained in:
daywalker90 2026-08-09 01:38:27 +02:00
parent b2078bab81
commit f79db424cd
5 changed files with 47 additions and 62 deletions

View file

@ -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<PluginState>,
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

View file

@ -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<PluginState>,
params: nip47::PayInvoiceRequest,
@ -63,10 +64,7 @@ async fn pay_invoice(
let nwc_store =
load_nwc_and_check_budget(&mut rpc, label, &params, 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<bool, (nip47::NIP47Error, Option<String>)> {
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,

View file

@ -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::<Vec<_>>()
.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)?);

View file

@ -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<RelayUrl>,
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,
}
}
}

View file

@ -154,34 +154,6 @@ pub async fn save_event_id(
Ok(())
}
pub fn at_or_above_version(my_version: &str, min_version: &str) -> Result<bool, anyhow::Error> {
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<PluginState>) -> (String, String) {
let holdinvoice_support = plugin.state().hold_client.lock().is_some();