mirror of
https://github.com/daywalker90/cln-nip47.git
synced 2026-08-13 12:33:43 +02:00
use xkeysend on CLN v26.06+
This commit is contained in:
parent
b16db82693
commit
af306edd3a
3 changed files with 147 additions and 69 deletions
|
|
@ -6,6 +6,9 @@
|
|||
- holdinvoice methods: ``make_hold_invoice``, ``cancel_hold_invoice``, ``settle_hold_invoice``
|
||||
- holdinvoice notification: ``hold_invoice_accepted``
|
||||
|
||||
### Changed
|
||||
- `pay_keysend` will use the new CLN `xkeysend` command using CLN v26.06+
|
||||
|
||||
### Removed
|
||||
- ``multi_pay_invoice`` and ``multi_pay_keysend``, they were removed from the spec
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
use std::str::FromStr;
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
use cln_plugin::Plugin;
|
||||
use cln_rpc::{
|
||||
model::requests::KeysendRequest,
|
||||
model::requests::{KeysendRequest, XkeysendRequest},
|
||||
primitives::{Amount, PublicKey, TlvEntry, TlvStream},
|
||||
};
|
||||
use nostr::nips::nip47;
|
||||
|
||||
use crate::{
|
||||
structs::PluginState,
|
||||
util::{budget_amount_check, load_nwc_store, update_nwc_store},
|
||||
util::{at_or_above_version, budget_amount_check, load_nwc_store, update_nwc_store},
|
||||
};
|
||||
|
||||
pub async fn pay_keysend_response(
|
||||
|
|
@ -76,75 +76,147 @@ async fn pay_keysend(
|
|||
message: e.to_string(),
|
||||
})?;
|
||||
|
||||
let mut extratlvs = TlvStream {
|
||||
entries: Vec::new(),
|
||||
};
|
||||
for tlv in params.tlv_records {
|
||||
extratlvs.entries.push(TlvEntry {
|
||||
typ: tlv.tlv_type,
|
||||
value: tlv.value.as_bytes().to_owned(),
|
||||
});
|
||||
}
|
||||
let extratlvs = if extratlvs.entries.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(extratlvs)
|
||||
};
|
||||
let my_cln_version = plugin.state().config.lock().my_cln_version.clone();
|
||||
|
||||
match rpc
|
||||
.call_typed(&KeysendRequest {
|
||||
exemptfee: None,
|
||||
extratlvs,
|
||||
label: None,
|
||||
maxdelay: None,
|
||||
maxfee: None,
|
||||
maxfeepercent: None,
|
||||
retry_for: None,
|
||||
routehints: None,
|
||||
amount_msat: Amount::from_msat(params.amount),
|
||||
destination: pubkey,
|
||||
})
|
||||
.await
|
||||
{
|
||||
Ok(o) => {
|
||||
if let Some(ref mut bdg) = nwc_store.budget_msat {
|
||||
*bdg = bdg.saturating_sub(o.amount_sent_msat.msat());
|
||||
update_nwc_store(&mut rpc, label, nwc_store)
|
||||
.await
|
||||
.map_err(|e| nip47::NIP47Error {
|
||||
if at_or_above_version(&my_cln_version, "26.06").map_err(|e| nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Other,
|
||||
message: e.to_string(),
|
||||
})? {
|
||||
let mut extratlvs = HashMap::with_capacity(params.tlv_records.len());
|
||||
for tlv in params.tlv_records {
|
||||
extratlvs.insert(tlv.tlv_type.to_string(), tlv.value);
|
||||
}
|
||||
let extratlvs = if extratlvs.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(extratlvs)
|
||||
};
|
||||
|
||||
match rpc
|
||||
.call_typed(&XkeysendRequest {
|
||||
extratlvs,
|
||||
label: None,
|
||||
maxdelay: None,
|
||||
maxfee: None,
|
||||
retry_for: None,
|
||||
layers: None,
|
||||
amount_msat: Amount::from_msat(params.amount),
|
||||
destination: pubkey,
|
||||
})
|
||||
.await
|
||||
{
|
||||
Ok(o) => {
|
||||
if let Some(ref mut bdg) = nwc_store.budget_msat {
|
||||
*bdg = bdg.saturating_sub(o.amount_sent_msat.msat());
|
||||
update_nwc_store(&mut rpc, label, nwc_store)
|
||||
.await
|
||||
.map_err(|e| nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Internal,
|
||||
message: e.to_string(),
|
||||
})?;
|
||||
}
|
||||
|
||||
let preimage = hex::encode(o.payment_preimage.to_vec());
|
||||
|
||||
let fees_paid = o.amount_sent_msat.msat() - o.amount_msat.msat();
|
||||
|
||||
Ok(nip47::PayKeysendResponse {
|
||||
preimage,
|
||||
fees_paid: Some(fees_paid),
|
||||
})
|
||||
}
|
||||
Err(e) => match e.code {
|
||||
Some(c) => match c {
|
||||
203 | 205 | 207 | 219 => Err(nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::PaymentFailed,
|
||||
message: e.to_string(),
|
||||
}),
|
||||
209 => Err(nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Other,
|
||||
message: e.to_string(),
|
||||
}),
|
||||
_ => Err(nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Internal,
|
||||
message: e.to_string(),
|
||||
})?;
|
||||
}
|
||||
|
||||
let preimage = hex::encode(o.payment_preimage.to_vec());
|
||||
|
||||
let fees_paid = o.amount_sent_msat.msat() - o.amount_msat.msat();
|
||||
|
||||
Ok(nip47::PayKeysendResponse {
|
||||
preimage,
|
||||
fees_paid: Some(fees_paid),
|
||||
})
|
||||
}
|
||||
Err(e) => match e.code {
|
||||
Some(c) => match c {
|
||||
203 | 205 | 210 => Err(nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::PaymentFailed,
|
||||
message: e.to_string(),
|
||||
}),
|
||||
206 => Err(nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::InsufficientBalance,
|
||||
message: e.to_string(),
|
||||
}),
|
||||
_ => Err(nip47::NIP47Error {
|
||||
}),
|
||||
},
|
||||
None => Err(nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Internal,
|
||||
message: e.to_string(),
|
||||
}),
|
||||
},
|
||||
None => Err(nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Internal,
|
||||
message: e.to_string(),
|
||||
}),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
let mut extratlvs = TlvStream {
|
||||
entries: Vec::new(),
|
||||
};
|
||||
for tlv in params.tlv_records {
|
||||
extratlvs.entries.push(TlvEntry {
|
||||
typ: tlv.tlv_type,
|
||||
value: tlv.value.as_bytes().to_owned(),
|
||||
});
|
||||
}
|
||||
let extratlvs = if extratlvs.entries.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(extratlvs)
|
||||
};
|
||||
|
||||
match rpc
|
||||
.call_typed(&KeysendRequest {
|
||||
exemptfee: None,
|
||||
extratlvs,
|
||||
label: None,
|
||||
maxdelay: None,
|
||||
maxfee: None,
|
||||
maxfeepercent: None,
|
||||
retry_for: None,
|
||||
routehints: None,
|
||||
amount_msat: Amount::from_msat(params.amount),
|
||||
destination: pubkey,
|
||||
})
|
||||
.await
|
||||
{
|
||||
Ok(o) => {
|
||||
if let Some(ref mut bdg) = nwc_store.budget_msat {
|
||||
*bdg = bdg.saturating_sub(o.amount_sent_msat.msat());
|
||||
update_nwc_store(&mut rpc, label, nwc_store)
|
||||
.await
|
||||
.map_err(|e| nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Internal,
|
||||
message: e.to_string(),
|
||||
})?;
|
||||
}
|
||||
|
||||
let preimage = hex::encode(o.payment_preimage.to_vec());
|
||||
|
||||
let fees_paid = o.amount_sent_msat.msat() - o.amount_msat.msat();
|
||||
|
||||
Ok(nip47::PayKeysendResponse {
|
||||
preimage,
|
||||
fees_paid: Some(fees_paid),
|
||||
})
|
||||
}
|
||||
Err(e) => match e.code {
|
||||
Some(c) => match c {
|
||||
203 | 205 | 210 => Err(nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::PaymentFailed,
|
||||
message: e.to_string(),
|
||||
}),
|
||||
206 => Err(nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::InsufficientBalance,
|
||||
message: e.to_string(),
|
||||
}),
|
||||
_ => Err(nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Internal,
|
||||
message: e.to_string(),
|
||||
}),
|
||||
},
|
||||
None => Err(nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Internal,
|
||||
message: e.to_string(),
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
use cln_plugin::Plugin;
|
||||
use cln_rpc::{
|
||||
ClnRpc,
|
||||
RpcError,
|
||||
model::{
|
||||
requests::{DecodeRequest, PayRequest, XpayRequest},
|
||||
responses::DecodeResponse,
|
||||
},
|
||||
primitives::{Amount, Secret},
|
||||
ClnRpc,
|
||||
RpcError,
|
||||
};
|
||||
use nostr::nips::nip47;
|
||||
|
||||
use crate::{
|
||||
structs::{NwcStore, PluginState, NOT_INV_ERR},
|
||||
structs::{NOT_INV_ERR, NwcStore, PluginState},
|
||||
util::{at_or_above_version, budget_amount_check, load_nwc_store, update_nwc_store},
|
||||
};
|
||||
|
||||
|
|
@ -316,6 +316,9 @@ async fn pay_with_xpay_full(
|
|||
layers: None,
|
||||
invstring: params.invoice,
|
||||
payer_note: None,
|
||||
dev_use_shadow: None,
|
||||
label: None,
|
||||
localinvreqid: None,
|
||||
})
|
||||
.await
|
||||
.map_err(|e| map_cln_error_to_nip47(&e, id, true))?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue