mirror of
https://github.com/daywalker90/cln-nip47.git
synced 2026-08-13 12:33:43 +02:00
clippy fixes
This commit is contained in:
parent
f6d63920e5
commit
adbaa048dd
14 changed files with 131 additions and 120 deletions
32
src/main.rs
32
src/main.rs
|
|
@ -7,7 +7,7 @@ use cln_plugin::{
|
|||
};
|
||||
use cln_rpc::{model::requests::ListdatastoreRequest, ClnRpc};
|
||||
|
||||
use nostr_sdk::*;
|
||||
use nostr_sdk::nips::nip47;
|
||||
use nwc::run_nwc;
|
||||
use nwc_notifications::{payment_received_handler, payment_sent_handler};
|
||||
use parse::read_startup_options;
|
||||
|
|
@ -40,18 +40,18 @@ const OPT_NOTIFICATIONS: DefaultBooleanConfigOption = ConfigOption::new_bool_wit
|
|||
"Enable/disable nip47-notifications. Default is `true`",
|
||||
);
|
||||
pub const PLUGIN_NAME: &str = "cln-nip47";
|
||||
pub const WALLET_READ_METHODS: [nips::nip47::Method; 5] = [
|
||||
nips::nip47::Method::MakeInvoice,
|
||||
nips::nip47::Method::LookupInvoice,
|
||||
nips::nip47::Method::ListTransactions,
|
||||
nips::nip47::Method::GetBalance,
|
||||
nips::nip47::Method::GetInfo,
|
||||
pub const WALLET_READ_METHODS: [nip47::Method; 5] = [
|
||||
nip47::Method::MakeInvoice,
|
||||
nip47::Method::LookupInvoice,
|
||||
nip47::Method::ListTransactions,
|
||||
nip47::Method::GetBalance,
|
||||
nip47::Method::GetInfo,
|
||||
];
|
||||
pub const WALLET_ALL_METHODS: [nips::nip47::Method; 9] = [
|
||||
nips::nip47::Method::PayInvoice,
|
||||
nips::nip47::Method::MultiPayInvoice,
|
||||
nips::nip47::Method::PayKeysend,
|
||||
nips::nip47::Method::MultiPayKeysend,
|
||||
pub const WALLET_ALL_METHODS: [nip47::Method; 9] = [
|
||||
nip47::Method::PayInvoice,
|
||||
nip47::Method::MultiPayInvoice,
|
||||
nip47::Method::PayKeysend,
|
||||
nip47::Method::MultiPayKeysend,
|
||||
WALLET_READ_METHODS[0],
|
||||
WALLET_READ_METHODS[1],
|
||||
WALLET_READ_METHODS[2],
|
||||
|
|
@ -90,13 +90,13 @@ async fn main() -> Result<(), anyhow::Error> {
|
|||
Ok(state) => state,
|
||||
Err(e) => {
|
||||
return plugin
|
||||
.disable(format!("Error connecting to cln rpc: {}", e).as_str())
|
||||
.disable(format!("Error connecting to cln rpc: {e}").as_str())
|
||||
.await;
|
||||
}
|
||||
};
|
||||
match read_startup_options(&plugin, &state).await {
|
||||
Ok(()) => &(),
|
||||
Err(e) => return plugin.disable(format!("{}", e).as_str()).await,
|
||||
Err(e) => return plugin.disable(format!("{e}").as_str()).await,
|
||||
};
|
||||
log::debug!("read startup options done");
|
||||
plugin
|
||||
|
|
@ -113,7 +113,7 @@ async fn main() -> Result<(), anyhow::Error> {
|
|||
time::sleep(Duration::from_secs(1)).await;
|
||||
|
||||
match load_nwcs(plugin.clone(), &mut rpc).await {
|
||||
Ok(_) => log::info!("All NWC's loaded"),
|
||||
Ok(()) => log::info!("All NWC's loaded"),
|
||||
Err(e) => {
|
||||
println!(
|
||||
"{}",
|
||||
|
|
@ -146,7 +146,7 @@ async fn load_nwcs(plugin: Plugin<PluginState>, rpc: &mut ClnRpc) -> Result<(),
|
|||
key: Some(vec![PLUGIN_NAME.to_owned()]),
|
||||
})
|
||||
.await?;
|
||||
for datastore in labels.datastore.into_iter() {
|
||||
for datastore in labels.datastore {
|
||||
let label = datastore.key.last().unwrap();
|
||||
let mut nwc_store = load_nwc_store(rpc, label).await?;
|
||||
|
||||
|
|
|
|||
85
src/nwc.rs
85
src/nwc.rs
|
|
@ -12,9 +12,25 @@ use crate::util::is_read_only_nwc;
|
|||
use crate::{OPT_NOTIFICATIONS, WALLET_ALL_METHODS, WALLET_READ_METHODS};
|
||||
use anyhow::anyhow;
|
||||
use cln_plugin::Plugin;
|
||||
use nostr_sdk::nips::*;
|
||||
use nostr_sdk::client;
|
||||
use nostr_sdk::nips::nip04;
|
||||
use nostr_sdk::nips::nip44;
|
||||
use nostr_sdk::nips::nip47;
|
||||
use nostr_sdk::nostr::Filter;
|
||||
use nostr_sdk::nostr::Kind;
|
||||
use nostr_sdk::nostr::Tag;
|
||||
use nostr_sdk::Alphabet;
|
||||
use nostr_sdk::Client;
|
||||
use nostr_sdk::*;
|
||||
use nostr_sdk::EventBuilder;
|
||||
use nostr_sdk::Keys;
|
||||
use nostr_sdk::PublicKey;
|
||||
use nostr_sdk::RelayPoolNotification;
|
||||
use nostr_sdk::RelayStatus;
|
||||
use nostr_sdk::SecretKey;
|
||||
use nostr_sdk::SignerError;
|
||||
use nostr_sdk::SingleLetterTag;
|
||||
use nostr_sdk::TagKind;
|
||||
use nostr_sdk::Timestamp;
|
||||
use tokio::sync::oneshot;
|
||||
use tokio::time;
|
||||
|
||||
|
|
@ -39,13 +55,13 @@ pub async fn run_nwc(
|
|||
|
||||
log::debug!("relay_count:{}", nwc_store.uri.relays.len());
|
||||
|
||||
for relay in nwc_store.uri.relays.iter() {
|
||||
log::debug!("Adding relay: {}", relay);
|
||||
for relay in &nwc_store.uri.relays {
|
||||
log::debug!("Adding relay: {relay}");
|
||||
client.add_relay(relay).await?;
|
||||
}
|
||||
|
||||
if nwc_store.interval_config.is_some() {
|
||||
start_nwc_budget_job(plugin.clone(), label.clone());
|
||||
start_nwc_budget_job(&plugin, label.clone());
|
||||
}
|
||||
|
||||
let client_clone = client.clone();
|
||||
|
|
@ -67,7 +83,7 @@ pub async fn run_nwc(
|
|||
if relay.status() == RelayStatus::Connected {
|
||||
connected = true;
|
||||
} else {
|
||||
log::info!("Could not connect to {}", url)
|
||||
log::info!("Could not connect to {url}");
|
||||
}
|
||||
}
|
||||
if !connected {
|
||||
|
|
@ -84,7 +100,7 @@ pub async fn run_nwc(
|
|||
)
|
||||
.await
|
||||
{
|
||||
log::warn!("{}", e);
|
||||
log::warn!("{e}");
|
||||
client_clone.disconnect().await;
|
||||
time::sleep(Duration::from_secs(5)).await;
|
||||
continue;
|
||||
|
|
@ -95,11 +111,11 @@ pub async fn run_nwc(
|
|||
.author(client_pubkey);
|
||||
|
||||
if let Err(e) = client_clone.subscribe(filter, None).await {
|
||||
log::warn!("Could not subscribe to nwc events! {}", e);
|
||||
log::warn!("Could not subscribe to nwc events! {e}");
|
||||
client_clone.disconnect().await;
|
||||
time::sleep(Duration::from_secs(5)).await;
|
||||
continue;
|
||||
};
|
||||
}
|
||||
|
||||
let client_clone_handler = client_clone.clone();
|
||||
match client_clone
|
||||
|
|
@ -120,10 +136,10 @@ pub async fn run_nwc(
|
|||
.await
|
||||
{
|
||||
Ok(()) => {
|
||||
log::info!("NWC handler for `{}` stopped", label_clone);
|
||||
log::info!("NWC handler for `{label_clone}` stopped");
|
||||
break;
|
||||
}
|
||||
Err(e) => log::warn!("NWC handler for `{}` had an error: {}", label_clone, e),
|
||||
Err(e) => log::warn!("NWC handler for `{label_clone}` had an error: {e}"),
|
||||
};
|
||||
}
|
||||
});
|
||||
|
|
@ -147,20 +163,20 @@ pub async fn send_nwc_info_event(
|
|||
|
||||
if notifications {
|
||||
info_event_builder = info_event_builder
|
||||
.tag(Tag::parse(vec!["notifications", "payment_received payment_sent"]).unwrap())
|
||||
.tag(Tag::parse(vec!["notifications", "payment_received payment_sent"]).unwrap());
|
||||
}
|
||||
|
||||
let info_event = match info_event_builder.sign_with_keys(&wallet_keys) {
|
||||
Ok(o) => o,
|
||||
Err(e) => {
|
||||
return Err(anyhow!("Could not sign info_event! {}", e));
|
||||
return Err(anyhow!("Could not sign info_event! {e}"));
|
||||
}
|
||||
};
|
||||
log::debug!("info_event:{:?}", info_event);
|
||||
log::debug!("info_event:{info_event:?}");
|
||||
let send_result = match client.send_event(&info_event).await {
|
||||
Ok(o) => o,
|
||||
Err(e) => {
|
||||
return Err(anyhow!("Could not send info_event! {}", e));
|
||||
return Err(anyhow!("Could not send info_event! {e}"));
|
||||
}
|
||||
};
|
||||
if send_result.success.is_empty() {
|
||||
|
|
@ -182,16 +198,16 @@ pub async fn stop_nwc(plugin: Plugin<PluginState>, label: &String) {
|
|||
client.shutdown().await;
|
||||
}
|
||||
|
||||
stop_nwc_budget_job(plugin.clone(), label);
|
||||
stop_nwc_budget_job(&plugin, label);
|
||||
}
|
||||
|
||||
pub fn start_nwc_budget_job(plugin: Plugin<PluginState>, label: String) {
|
||||
pub fn start_nwc_budget_job(plugin: &Plugin<PluginState>, label: String) {
|
||||
let (tx, rx) = oneshot::channel::<()>();
|
||||
tokio::spawn(budget_task(rx, plugin.clone(), label.clone()));
|
||||
plugin.state().budget_jobs.lock().insert(label, tx);
|
||||
}
|
||||
|
||||
pub fn stop_nwc_budget_job(plugin: Plugin<PluginState>, label: &String) {
|
||||
pub fn stop_nwc_budget_job(plugin: &Plugin<PluginState>, label: &String) {
|
||||
let mut budget_jobs = plugin.state().budget_jobs.lock();
|
||||
let job = budget_jobs.remove(label);
|
||||
if let Some(j) = job {
|
||||
|
|
@ -206,7 +222,7 @@ async fn nwc_request_handler(
|
|||
label: String,
|
||||
wallet_keys: Keys,
|
||||
client_pubkey: PublicKey,
|
||||
) -> Result<bool> {
|
||||
) -> Result<bool, Box<dyn std::error::Error>> {
|
||||
let (relay_url, subscription_id, event) = match notification {
|
||||
RelayPoolNotification::Event {
|
||||
relay_url,
|
||||
|
|
@ -225,12 +241,7 @@ async fn nwc_request_handler(
|
|||
return Ok(false);
|
||||
}
|
||||
}
|
||||
log::debug!(
|
||||
"relay_url:{} subscription_id:{} {:?}",
|
||||
relay_url,
|
||||
subscription_id,
|
||||
event
|
||||
);
|
||||
log::debug!("relay_url:{relay_url} subscription_id:{subscription_id} {event:?}");
|
||||
let use_nip44;
|
||||
let content = match nip44::decrypt(wallet_keys.secret_key(), &client_pubkey, &event.content) {
|
||||
Ok(o) => {
|
||||
|
|
@ -238,24 +249,24 @@ async fn nwc_request_handler(
|
|||
o
|
||||
}
|
||||
Err(e) => {
|
||||
log::debug!("Could not decrypt using NIP-44:{}. Trying NIP-04", e);
|
||||
log::debug!("Could not decrypt using NIP-44:{e}. Trying NIP-04");
|
||||
match nip04::decrypt(wallet_keys.secret_key(), &client_pubkey, &event.content) {
|
||||
Ok(o) => {
|
||||
use_nip44 = false;
|
||||
o
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("Could not decrypt using NIP-04 or NIP-44:{}", e);
|
||||
log::warn!("Could not decrypt using NIP-04 or NIP-44:{e}");
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
log::debug!("Decrypted:{}", content);
|
||||
log::debug!("Decrypted:{content}");
|
||||
let request: nip47::Request = match serde_json::from_str(&content) {
|
||||
Ok(o) => o,
|
||||
Err(e) => {
|
||||
log::warn!("Error parsing nip47::Request! {}", e);
|
||||
log::warn!("Error parsing nip47::Request! {e}");
|
||||
return Ok(false);
|
||||
}
|
||||
};
|
||||
|
|
@ -462,15 +473,15 @@ async fn nwc_request_handler(
|
|||
)]
|
||||
}
|
||||
};
|
||||
for (response, id) in responses.into_iter() {
|
||||
for (response, id) in responses {
|
||||
let response_str = match serde_json::to_string(&response) {
|
||||
Ok(o) => o,
|
||||
Err(e) => {
|
||||
log::warn!("Error serializing response! {}", e);
|
||||
log::warn!("Error serializing response! {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
log::debug!("RESPONSE:{}", response_str);
|
||||
log::debug!("RESPONSE:{response_str}");
|
||||
|
||||
let content = if use_nip44 {
|
||||
match nip44::encrypt(
|
||||
|
|
@ -481,7 +492,7 @@ async fn nwc_request_handler(
|
|||
) {
|
||||
Ok(o) => o,
|
||||
Err(e) => {
|
||||
log::warn!("Error encrypting response with nip44! {}", e);
|
||||
log::warn!("Error encrypting response with nip44! {e}");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -489,7 +500,7 @@ async fn nwc_request_handler(
|
|||
match nip04::encrypt(wallet_keys.secret_key(), &client_pubkey, response_str) {
|
||||
Ok(o) => o,
|
||||
Err(e) => {
|
||||
log::warn!("Error encrypting response with nip04! {}", e);
|
||||
log::warn!("Error encrypting response with nip04! {e}");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -509,14 +520,14 @@ async fn nwc_request_handler(
|
|||
let response_event = match response_builder.sign_with_keys(&wallet_keys) {
|
||||
Ok(o) => o,
|
||||
Err(e) => {
|
||||
log::warn!("Error signing reponse event! {}", e);
|
||||
log::warn!("Error signing reponse event! {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let send_result = match client.send_event(&response_event).await {
|
||||
Ok(o) => o,
|
||||
Err(e) => {
|
||||
log::warn!("Error sending response event! {}", e);
|
||||
log::warn!("Error sending response event! {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
|
@ -531,7 +542,7 @@ async fn nwc_request_handler(
|
|||
);
|
||||
continue;
|
||||
}
|
||||
log::debug!("SENT RESPONSE {:?}", response_event);
|
||||
log::debug!("SENT RESPONSE {response_event:?}");
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use cln_plugin::Plugin;
|
||||
use cln_rpc::{model::requests::ListpeerchannelsRequest, primitives::ChannelState};
|
||||
use nostr_sdk::nips::*;
|
||||
use nostr_sdk::nips::nip47;
|
||||
|
||||
use crate::{structs::PluginState, util::load_nwc_store};
|
||||
|
||||
|
|
@ -34,7 +34,7 @@ pub async fn get_balance(
|
|||
|| chan.state == ChannelState::CHANNELD_AWAITING_SPLICE
|
||||
{
|
||||
if let Some(spend) = chan.spendable_msat {
|
||||
amount_msat += spend.msat()
|
||||
amount_msat += spend.msat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
use cln_plugin::Plugin;
|
||||
use cln_rpc::model::requests::GetinfoRequest;
|
||||
use nostr_sdk::nips::*;
|
||||
use nostr_sdk::*;
|
||||
|
||||
use crate::structs::PluginState;
|
||||
use crate::util::{is_read_only_nwc, load_nwc_store};
|
||||
use crate::{OPT_NOTIFICATIONS, WALLET_ALL_METHODS, WALLET_READ_METHODS};
|
||||
use nostr_sdk::nips::nip47;
|
||||
|
||||
pub async fn get_info(
|
||||
plugin: Plugin<PluginState>,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use cln_rpc::{
|
|||
model::requests::InvoiceRequest,
|
||||
primitives::{Amount, AmountOrAny, Sha256},
|
||||
};
|
||||
use nostr_sdk::nips::*;
|
||||
use nostr_sdk::nips::nip47;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::structs::PluginState;
|
||||
|
|
@ -27,7 +27,7 @@ pub async fn make_invoice(
|
|||
}
|
||||
let description = params.description.as_ref().unwrap();
|
||||
let my_description_hash = Sha256::const_hash(description.as_bytes());
|
||||
let description_hash = Sha256::from_str(&d_hash).map_err(|e| nip47::NIP47Error {
|
||||
let description_hash = Sha256::from_str(d_hash).map_err(|e| nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Internal,
|
||||
message: e.to_string(),
|
||||
})?;
|
||||
|
|
@ -37,7 +37,7 @@ pub async fn make_invoice(
|
|||
message: "description_hash not matching description".to_owned(),
|
||||
});
|
||||
}
|
||||
deschashonly = Some(true)
|
||||
deschashonly = Some(true);
|
||||
}
|
||||
|
||||
match rpc
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use cln_rpc::{
|
|||
model::requests::KeysendRequest,
|
||||
primitives::{Amount, PublicKey, TlvEntry, TlvStream},
|
||||
};
|
||||
use nostr_sdk::nips::*;
|
||||
use nostr_sdk::nips::nip47;
|
||||
use tokio::time;
|
||||
|
||||
use crate::{
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ use cln_rpc::{
|
|||
},
|
||||
primitives::Sha256,
|
||||
};
|
||||
use nostr_sdk::nips::*;
|
||||
use nostr_sdk::*;
|
||||
use nostr_sdk::nips::nip47;
|
||||
use nostr_sdk::Timestamp;
|
||||
|
||||
use crate::structs::PluginState;
|
||||
|
||||
|
|
@ -307,7 +307,7 @@ pub async fn list_transactions(
|
|||
})?
|
||||
.invoices;
|
||||
|
||||
for list_invoice in list_invoices.into_iter() {
|
||||
for list_invoice in list_invoices {
|
||||
if list_invoice.status == ListinvoicesInvoicesStatus::EXPIRED {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -386,7 +386,7 @@ pub async fn list_transactions(
|
|||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
|
||||
invoice_decoded.invoice_relative_expiry.map(|e_at| {
|
||||
Timestamp::from_secs(
|
||||
invoice_decoded.invoice_created_at.unwrap() + (e_at as u64),
|
||||
invoice_decoded.invoice_created_at.unwrap() + u64::from(e_at),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
@ -440,7 +440,7 @@ pub async fn list_transactions(
|
|||
})?
|
||||
.pays;
|
||||
|
||||
for list_pay in list_pays.into_iter() {
|
||||
for list_pay in list_pays {
|
||||
if list_pay.status != ListpaysPaysStatus::COMPLETE {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -543,7 +543,7 @@ pub async fn list_transactions(
|
|||
|
||||
if let Some(l) = params.limit {
|
||||
if transactions.len() > (l as usize) {
|
||||
transactions = transactions.drain(0..(l as usize)).collect()
|
||||
transactions = transactions.drain(0..(l as usize)).collect();
|
||||
}
|
||||
}
|
||||
transactions = trim_to_size(transactions, 127 * 1024);
|
||||
|
|
@ -566,12 +566,11 @@ fn trim_to_size(
|
|||
max_size
|
||||
);
|
||||
return transactions;
|
||||
} else {
|
||||
transactions.pop();
|
||||
}
|
||||
transactions.pop();
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("Failed to serialize transactions: {}", e);
|
||||
log::warn!("Failed to serialize transactions: {e}");
|
||||
return transactions;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,11 @@ use cln_rpc::primitives::Sha256;
|
|||
use crate::structs::PluginState;
|
||||
use crate::OPT_NOTIFICATIONS;
|
||||
|
||||
use nostr_sdk::nips::*;
|
||||
use nostr_sdk::*;
|
||||
use nostr_sdk::nips::nip47;
|
||||
use nostr_sdk::nostr::EventBuilder;
|
||||
use nostr_sdk::nostr::Kind;
|
||||
use nostr_sdk::nostr::Tag;
|
||||
use nostr_sdk::Timestamp;
|
||||
|
||||
pub async fn payment_received_handler(
|
||||
plugin: Plugin<PluginState>,
|
||||
|
|
@ -141,7 +144,7 @@ pub async fn payment_received_handler(
|
|||
}),
|
||||
};
|
||||
let notification = serde_json::to_string(&content)?;
|
||||
log::debug!("NOTIFICATION: {}", notification);
|
||||
log::debug!("NOTIFICATION: {notification}");
|
||||
let content_encrypted_nip04 = signer.nip04_encrypt(client_pubkey, ¬ification).await?;
|
||||
let event_nip04 = EventBuilder::new(Kind::from_u16(23196), content_encrypted_nip04)
|
||||
.tag(Tag::public_key(*client_pubkey))
|
||||
|
|
@ -156,9 +159,9 @@ pub async fn payment_received_handler(
|
|||
.into_values()
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ")
|
||||
)
|
||||
);
|
||||
}
|
||||
log::debug!("NIP04 NOTIFICATION SENT: {:?}", event_nip04);
|
||||
log::debug!("NIP04 NOTIFICATION SENT: {event_nip04:?}");
|
||||
|
||||
let content_encrypted_nip44 = signer.nip44_encrypt(client_pubkey, ¬ification).await?;
|
||||
let event_nip44 = EventBuilder::new(Kind::from_u16(23197), content_encrypted_nip44)
|
||||
|
|
@ -174,9 +177,9 @@ pub async fn payment_received_handler(
|
|||
.into_values()
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ")
|
||||
)
|
||||
);
|
||||
}
|
||||
log::debug!("NIP44 NOTIFICATION SENT: {:?}", event_nip44);
|
||||
log::debug!("NIP44 NOTIFICATION SENT: {event_nip44:?}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
@ -239,7 +242,16 @@ pub async fn payment_sent_handler(
|
|||
);
|
||||
let settled_at = Timestamp::from_secs(pay.completed_at.unwrap());
|
||||
|
||||
if !invstring.is_empty() {
|
||||
if invstring.is_empty() {
|
||||
description = pay.description.clone();
|
||||
description_hash = None;
|
||||
amount = if let Some(amt) = pay.amount_msat {
|
||||
amt.msat()
|
||||
} else {
|
||||
// Amount missing but required
|
||||
0
|
||||
}
|
||||
} else {
|
||||
let invoice_decoded = rpc
|
||||
.call_typed(&DecodeRequest {
|
||||
string: invstring.clone(),
|
||||
|
|
@ -282,15 +294,6 @@ pub async fn payment_sent_handler(
|
|||
}
|
||||
_ => return not_invoice_err,
|
||||
};
|
||||
} else {
|
||||
description = pay.description.clone();
|
||||
description_hash = None;
|
||||
amount = if let Some(amt) = pay.amount_msat {
|
||||
amt.msat()
|
||||
} else {
|
||||
// Amount missing but required
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
let fees_paid = pay.amount_sent_msat.unwrap().msat() - amount;
|
||||
|
|
@ -324,7 +327,7 @@ pub async fn payment_sent_handler(
|
|||
}),
|
||||
};
|
||||
let notification = serde_json::to_string(&content)?;
|
||||
log::debug!("NOTIFICATION: {}", notification);
|
||||
log::debug!("NOTIFICATION: {notification}");
|
||||
let content_encrypted_nip04 = signer.nip04_encrypt(client_pubkey, ¬ification).await?;
|
||||
let event_nip04 = EventBuilder::new(Kind::from_u16(23196), content_encrypted_nip04)
|
||||
.tag(Tag::public_key(*client_pubkey))
|
||||
|
|
@ -339,9 +342,9 @@ pub async fn payment_sent_handler(
|
|||
.into_values()
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ")
|
||||
)
|
||||
);
|
||||
}
|
||||
log::debug!("NIP04 NOTIFICATION SENT: {:?}", event_nip04);
|
||||
log::debug!("NIP04 NOTIFICATION SENT: {event_nip04:?}");
|
||||
|
||||
let content_encrypted_nip44 = signer.nip44_encrypt(client_pubkey, ¬ification).await?;
|
||||
let event_nip44 = EventBuilder::new(Kind::from_u16(23197), content_encrypted_nip44)
|
||||
|
|
@ -357,9 +360,9 @@ pub async fn payment_sent_handler(
|
|||
.into_values()
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ")
|
||||
)
|
||||
);
|
||||
}
|
||||
log::debug!("NIP44 NOTIFICATION SENT: {:?}", event_nip44);
|
||||
log::debug!("NIP44 NOTIFICATION SENT: {event_nip44:?}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use cln_rpc::{
|
|||
model::requests::{DecodeRequest, PayRequest, XpayRequest},
|
||||
primitives::Amount,
|
||||
};
|
||||
use nostr_sdk::nips::*;
|
||||
use nostr_sdk::nips::nip47;
|
||||
use tokio::time;
|
||||
|
||||
use crate::{
|
||||
|
|
@ -54,7 +54,7 @@ pub async fn pay_invoice(
|
|||
} else {
|
||||
match invoice_decoded.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
|
||||
invoice_decoded.invoice_payment_hash.unwrap().to_string()
|
||||
invoice_decoded.invoice_payment_hash.unwrap()
|
||||
}
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
invoice_decoded.payment_hash.unwrap().to_string()
|
||||
|
|
|
|||
13
src/parse.rs
13
src/parse.rs
|
|
@ -14,14 +14,13 @@ pub async fn read_startup_options(
|
|||
state: &PluginState,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let relays_str = if let Some(relays) = plugin.option(&OPT_RELAYS).unwrap() {
|
||||
if !relays.is_empty() {
|
||||
relays
|
||||
} else {
|
||||
if relays.is_empty() {
|
||||
return Err(anyhow!(
|
||||
"Empty `{}` option, must specify atleast one relay url!",
|
||||
OPT_RELAYS.name()
|
||||
));
|
||||
}
|
||||
relays
|
||||
} else {
|
||||
return Err(anyhow!(
|
||||
"`{}` not set, must specify atleast one relay url!",
|
||||
|
|
@ -36,8 +35,8 @@ pub async fn read_startup_options(
|
|||
let version = rpc.call_typed(&GetinfoRequest {}).await?.version;
|
||||
let mut config = state.config.lock();
|
||||
config.my_cln_version = version;
|
||||
for relay in relays_str.into_iter() {
|
||||
log::debug!("RELAY:{}", relay);
|
||||
for relay in relays_str {
|
||||
log::debug!("RELAY:{relay}");
|
||||
config.relays.push(nostr_sdk::RelayUrl::parse(&relay)?);
|
||||
}
|
||||
Ok(())
|
||||
|
|
@ -58,9 +57,9 @@ pub fn parse_time_period(input: &str) -> Result<u64, anyhow::Error> {
|
|||
TimeUnit::Week => Ok(value * 60 * 60 * 24 * 7),
|
||||
}
|
||||
} else {
|
||||
Err(anyhow!(format!("Unsupported time unit: {}", unit)))
|
||||
Err(anyhow!(format!("Unsupported time unit: {unit}")))
|
||||
}
|
||||
} else {
|
||||
Err(anyhow!("Invalid time format: {}", input))
|
||||
Err(anyhow!("Invalid time format: {input}"))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
16
src/rpc.rs
16
src/rpc.rs
|
|
@ -3,8 +3,10 @@ use cln_plugin::Plugin;
|
|||
use cln_rpc::model::requests::{
|
||||
DatastoreMode, DatastoreRequest, DeldatastoreRequest, ListdatastoreRequest,
|
||||
};
|
||||
use nostr_sdk::nips::nip47::*;
|
||||
use nostr_sdk::*;
|
||||
use nostr_sdk::nips::nip47::NostrWalletConnectURI;
|
||||
use nostr_sdk::Keys;
|
||||
use nostr_sdk::SecretKey;
|
||||
use nostr_sdk::Timestamp;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::nwc::{
|
||||
|
|
@ -113,7 +115,7 @@ pub async fn nwc_budget(
|
|||
|
||||
let (label, budget_msat, interval_secs) = parse_full_args(args)?;
|
||||
|
||||
stop_nwc_budget_job(plugin.clone(), &label);
|
||||
stop_nwc_budget_job(&plugin, &label);
|
||||
|
||||
let mut nwc_store = load_nwc_store(&mut rpc, &label).await?;
|
||||
|
||||
|
|
@ -139,7 +141,7 @@ pub async fn nwc_budget(
|
|||
let is_new_nwc_read_only = is_read_only_nwc(&nwc_store);
|
||||
|
||||
if nwc_store.interval_config.is_some() {
|
||||
start_nwc_budget_job(plugin.clone(), label.clone());
|
||||
start_nwc_budget_job(&plugin, label.clone());
|
||||
}
|
||||
|
||||
update_nwc_store(&mut rpc, &label, nwc_store.clone()).await?;
|
||||
|
|
@ -155,7 +157,7 @@ pub async fn nwc_budget(
|
|||
send_nwc_info_event(
|
||||
clients
|
||||
.get(&label)
|
||||
.ok_or_else(|| anyhow!("No client found for label: {}", label))?
|
||||
.ok_or_else(|| anyhow!("No client found for label: {label}"))?
|
||||
.0
|
||||
.clone(),
|
||||
plugin.option(&OPT_NOTIFICATIONS).unwrap(),
|
||||
|
|
@ -195,14 +197,14 @@ pub async fn nwc_list(
|
|||
});
|
||||
nwcs.push(json!({lbl:nwc_json}));
|
||||
} else {
|
||||
let nwcs_store = rpc
|
||||
let all_stored_nwcs = rpc
|
||||
.call_typed(&ListdatastoreRequest {
|
||||
key: Some(vec![PLUGIN_NAME.to_owned()]),
|
||||
})
|
||||
.await?
|
||||
.datastore;
|
||||
|
||||
for datastore in nwcs_store.into_iter() {
|
||||
for datastore in all_stored_nwcs {
|
||||
let label = datastore.key.last().unwrap().to_owned();
|
||||
let nwc_store = load_nwc_store(&mut rpc, &label).await?;
|
||||
let wallet_key = Keys::new(SecretKey::from_hex(&nwc_store.walletkey)?);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ impl FromStr for TimeUnit {
|
|||
"hour" | "hours" | "h" => Ok(TimeUnit::Hour),
|
||||
"day" | "days" | "d" => Ok(TimeUnit::Day),
|
||||
"week" | "weeks" | "w" => Ok(TimeUnit::Week),
|
||||
_ => Err(format!("Unsupported time unit: {}", s)),
|
||||
_ => Err(format!("Unsupported time unit: {s}")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,17 +41,17 @@ pub async fn budget_task(
|
|||
);
|
||||
tokio::select! {
|
||||
_ = &mut rx => {
|
||||
log::info!("Stopping budget task for {}", label);
|
||||
log::info!("Stopping budget task for {label}");
|
||||
break;
|
||||
}
|
||||
_ = time::sleep(Duration::from_secs(next_reset)) => {
|
||||
log::info!("Refreshing budget for {}",label);
|
||||
log::info!("Refreshing budget for {label}");
|
||||
*nwc_store.budget_msat
|
||||
.as_mut()
|
||||
.ok_or_else(||anyhow!("budget_msat missing"))? = interval_config.reset_budget_msat;
|
||||
interval_config.last_reset = Timestamp::now().as_secs();
|
||||
update_nwc_store(&mut rpc, &label, nwc_store).await?;
|
||||
log::info!("Done refreshing budget for {}",label);
|
||||
log::info!("Done refreshing budget for {label}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
14
src/util.rs
14
src/util.rs
|
|
@ -12,10 +12,8 @@ pub fn budget_amount_check(
|
|||
budget_msat: Option<u64>,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
log::debug!(
|
||||
"checking budget and amounts for request:{:?} invoice:{:?} budget:{:?}",
|
||||
request_amt_msat,
|
||||
invoice_amt_msat,
|
||||
budget_msat
|
||||
"checking budget and amounts for request:{request_amt_msat:?} \
|
||||
invoice:{invoice_amt_msat:?} budget:{budget_msat:?}"
|
||||
);
|
||||
if request_amt_msat.is_none() && invoice_amt_msat.is_none() {
|
||||
return Err(anyhow!("No amount given to check budget against!"));
|
||||
|
|
@ -53,12 +51,12 @@ pub async fn load_nwc_store(rpc: &mut ClnRpc, label: &String) -> Result<NwcStore
|
|||
.datastore;
|
||||
let nwc_store_str = nwc_store_store
|
||||
.first()
|
||||
.ok_or_else(|| anyhow!("No datastore found for: {}", label))?
|
||||
.ok_or_else(|| anyhow!("No datastore found for: {label}"))?
|
||||
.string
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("Malformed nwc_store datastore: missing string"))?;
|
||||
let nwc_store: NwcStore = serde_json::from_str(nwc_store_str)?;
|
||||
log::debug!("loaded nwc store for label:{}", label);
|
||||
log::debug!("loaded nwc store for label:{label}");
|
||||
Ok(nwc_store)
|
||||
}
|
||||
|
||||
|
|
@ -75,7 +73,7 @@ pub async fn update_nwc_store(
|
|||
string: Some(serde_json::to_string(&nwc_store)?),
|
||||
})
|
||||
.await?;
|
||||
log::debug!("stored nwc store for label:{}", label);
|
||||
log::debug!("stored nwc store for label:{label}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -102,7 +100,7 @@ pub fn at_or_above_version(my_version: &str, min_version: &str) -> Result<bool,
|
|||
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));
|
||||
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()?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue