mirror of
https://github.com/daywalker90/cln-nip47.git
synced 2026-08-13 12:33:43 +02:00
refactor nwc_lookup
This commit is contained in:
parent
66e6378a72
commit
061b27653c
2 changed files with 228 additions and 393 deletions
|
|
@ -4,14 +4,17 @@ use cln_plugin::Plugin;
|
|||
use cln_rpc::{
|
||||
model::{
|
||||
requests::{DecodeRequest, ListinvoicesRequest, ListpaysRequest},
|
||||
responses::{ListinvoicesInvoicesStatus, ListpaysPaysStatus},
|
||||
responses::{
|
||||
ListinvoicesInvoices, ListinvoicesInvoicesStatus, ListpaysPays, ListpaysPaysStatus,
|
||||
},
|
||||
},
|
||||
primitives::Sha256,
|
||||
ClnRpc,
|
||||
};
|
||||
use nostr_sdk::nips::nip47;
|
||||
use nostr_sdk::Timestamp;
|
||||
|
||||
use crate::structs::PluginState;
|
||||
use crate::structs::{PluginState, NOT_INV_ERR};
|
||||
|
||||
pub async fn lookup_invoice(
|
||||
plugin: Plugin<PluginState>,
|
||||
|
|
@ -26,11 +29,6 @@ pub async fn lookup_invoice(
|
|||
});
|
||||
}
|
||||
|
||||
let not_invoice_err = Err(nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Other,
|
||||
message: "Not an invoice or invalid invoice".to_owned(),
|
||||
});
|
||||
|
||||
let invoice = if params.payment_hash.is_some() && params.invoice.is_some() {
|
||||
None
|
||||
} else {
|
||||
|
|
@ -56,92 +54,8 @@ pub async fn lookup_invoice(
|
|||
|
||||
if invoices.len() == 1 {
|
||||
let invoice_response = invoices.into_iter().next().unwrap();
|
||||
let invstring = if invoice_response.bolt11.is_some() {
|
||||
invoice_response.bolt11.unwrap()
|
||||
} else {
|
||||
invoice_response.bolt12.unwrap()
|
||||
};
|
||||
let invoice_decoded = rpc
|
||||
.call_typed(&DecodeRequest {
|
||||
string: invstring.clone(),
|
||||
})
|
||||
.await
|
||||
.map_err(|e| nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Internal,
|
||||
message: e.to_string(),
|
||||
})?;
|
||||
|
||||
if !invoice_decoded.valid {
|
||||
return not_invoice_err;
|
||||
}
|
||||
|
||||
let description = match invoice_decoded.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
|
||||
invoice_decoded.offer_description
|
||||
}
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => invoice_decoded.description,
|
||||
_ => return not_invoice_err,
|
||||
};
|
||||
let description_hash = match invoice_decoded.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => None,
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
invoice_decoded.description_hash.map(|h| h.to_string())
|
||||
}
|
||||
_ => return not_invoice_err,
|
||||
};
|
||||
|
||||
let amount = match invoice_decoded.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
|
||||
invoice_decoded.invoice_amount_msat.unwrap().msat()
|
||||
}
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
if let Some(amt) = invoice_decoded.amount_msat {
|
||||
amt.msat()
|
||||
} else if let Some(a) = invoice_response.amount_msat {
|
||||
a.msat()
|
||||
} else {
|
||||
// amount: `any` but have to put a value...
|
||||
0
|
||||
}
|
||||
}
|
||||
_ => return not_invoice_err,
|
||||
};
|
||||
|
||||
let created_at = match invoice_decoded.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
|
||||
Timestamp::from_secs(invoice_decoded.invoice_created_at.unwrap())
|
||||
}
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
Timestamp::from_secs(invoice_decoded.created_at.unwrap())
|
||||
}
|
||||
_ => return not_invoice_err,
|
||||
};
|
||||
|
||||
let preimage = invoice_response
|
||||
.payment_preimage
|
||||
.map(|p| hex::encode(p.to_vec()));
|
||||
|
||||
let state = match invoice_response.status {
|
||||
ListinvoicesInvoicesStatus::UNPAID => nip47::TransactionState::Pending,
|
||||
ListinvoicesInvoicesStatus::PAID => nip47::TransactionState::Settled,
|
||||
ListinvoicesInvoicesStatus::EXPIRED => nip47::TransactionState::Expired,
|
||||
};
|
||||
|
||||
Ok(nip47::LookupInvoiceResponse {
|
||||
transaction_type: Some(nip47::TransactionType::Incoming),
|
||||
invoice: Some(invstring),
|
||||
description,
|
||||
description_hash,
|
||||
preimage,
|
||||
payment_hash: invoice_response.payment_hash.to_string(),
|
||||
amount,
|
||||
fees_paid: 0,
|
||||
created_at,
|
||||
expires_at: Some(Timestamp::from_secs(invoice_response.expires_at)),
|
||||
settled_at: invoice_response.paid_at.map(Timestamp::from_secs),
|
||||
metadata: None,
|
||||
state: Some(state),
|
||||
})
|
||||
make_lookup_response_from_listinvoices(&mut rpc, invoice_response).await
|
||||
} else {
|
||||
let payment_hash_hash = if let Some(hash) = params.payment_hash {
|
||||
if let Ok(res) = Sha256::from_str(&hash) {
|
||||
|
|
@ -179,101 +93,8 @@ pub async fn lookup_invoice(
|
|||
});
|
||||
}
|
||||
let list_pay = pays.into_iter().next().unwrap();
|
||||
let invstring = if list_pay.bolt11.is_some() {
|
||||
list_pay.bolt11
|
||||
} else {
|
||||
list_pay.bolt12
|
||||
};
|
||||
|
||||
let invoice_decoded = if let Some(invstr) = &invstring {
|
||||
Some(
|
||||
rpc.call_typed(&DecodeRequest {
|
||||
string: invstr.clone(),
|
||||
})
|
||||
.await
|
||||
.map_err(|e| nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Internal,
|
||||
message: e.to_string(),
|
||||
})?,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if invoice_decoded.is_some() && !invoice_decoded.as_ref().unwrap().valid {
|
||||
return not_invoice_err;
|
||||
}
|
||||
|
||||
let description_hash = if let Some(inv_dec) = &invoice_decoded {
|
||||
match inv_dec.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => None,
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
inv_dec.description_hash.map(|h| h.to_string())
|
||||
}
|
||||
_ => return not_invoice_err,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let amount = if let Some(amt) = list_pay.amount_msat {
|
||||
amt.msat()
|
||||
} else if let Some(inv_dec) = &invoice_decoded {
|
||||
match inv_dec.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
|
||||
inv_dec.invoice_amount_msat.unwrap().msat()
|
||||
}
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
if let Some(amt) = inv_dec.amount_msat {
|
||||
amt.msat()
|
||||
} else {
|
||||
// amount: `any` but have to put a value...
|
||||
0
|
||||
}
|
||||
}
|
||||
_ => return not_invoice_err,
|
||||
}
|
||||
} else {
|
||||
return not_invoice_err;
|
||||
};
|
||||
|
||||
let description = if let Some(inv_dec) = invoice_decoded {
|
||||
match inv_dec.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => inv_dec.offer_description,
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => inv_dec.description,
|
||||
_ => return not_invoice_err,
|
||||
}
|
||||
} else {
|
||||
list_pay.description
|
||||
};
|
||||
|
||||
let fees_paid = if let Some(amt_sent) = list_pay.amount_sent_msat {
|
||||
amt_sent.msat() - amount
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let preimage = list_pay.preimage.map(|p| hex::encode(p.to_vec()));
|
||||
|
||||
let state = match list_pay.status {
|
||||
ListpaysPaysStatus::PENDING => nip47::TransactionState::Pending,
|
||||
ListpaysPaysStatus::FAILED => nip47::TransactionState::Failed,
|
||||
ListpaysPaysStatus::COMPLETE => nip47::TransactionState::Settled,
|
||||
};
|
||||
|
||||
Ok(nip47::LookupInvoiceResponse {
|
||||
transaction_type: Some(nip47::TransactionType::Outgoing),
|
||||
invoice: invstring,
|
||||
description,
|
||||
description_hash,
|
||||
preimage,
|
||||
payment_hash: list_pay.payment_hash.to_string(),
|
||||
amount,
|
||||
fees_paid,
|
||||
created_at: Timestamp::from_secs(list_pay.created_at),
|
||||
expires_at: None,
|
||||
settled_at: list_pay.completed_at.map(Timestamp::from_secs),
|
||||
metadata: None,
|
||||
state: Some(state),
|
||||
})
|
||||
make_lookup_response_from_listpays(&mut rpc, list_pay).await
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -316,112 +137,11 @@ pub async fn list_transactions(
|
|||
if !unpaid && list_invoice.status == ListinvoicesInvoicesStatus::UNPAID {
|
||||
continue;
|
||||
}
|
||||
let invstring = if list_invoice.bolt11.is_some() {
|
||||
list_invoice.bolt11.unwrap()
|
||||
} else {
|
||||
list_invoice.bolt12.unwrap()
|
||||
};
|
||||
|
||||
let invoice_decoded = rpc
|
||||
.call_typed(&DecodeRequest {
|
||||
string: invstring.clone(),
|
||||
})
|
||||
.await
|
||||
.map_err(|e| nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Internal,
|
||||
message: e.to_string(),
|
||||
})?;
|
||||
|
||||
if !invoice_decoded.valid {
|
||||
continue;
|
||||
match make_lookup_response_from_listinvoices(&mut rpc, list_invoice).await {
|
||||
Ok(t) => transactions.push(t),
|
||||
Err(_e) => (),
|
||||
}
|
||||
let created_at = match invoice_decoded.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
|
||||
Timestamp::from_secs(invoice_decoded.invoice_created_at.unwrap())
|
||||
}
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
Timestamp::from_secs(invoice_decoded.created_at.unwrap())
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
if let Some(f) = params.from {
|
||||
if created_at < f {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if let Some(u) = params.until {
|
||||
if created_at > u {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
let description = match invoice_decoded.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
|
||||
invoice_decoded.offer_description
|
||||
}
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
invoice_decoded.description
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
let description_hash = match invoice_decoded.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => None,
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
invoice_decoded.description_hash.map(|h| h.to_string())
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
let amount = match invoice_decoded.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
|
||||
invoice_decoded.invoice_amount_msat.unwrap().msat()
|
||||
}
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
if let Some(amt) = invoice_decoded.amount_msat {
|
||||
amt.msat()
|
||||
} else {
|
||||
// amount: `any` but have to put a value...
|
||||
0
|
||||
}
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
let expires_at = match invoice_decoded.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
|
||||
invoice_decoded.invoice_relative_expiry.map(|e_at| {
|
||||
Timestamp::from_secs(
|
||||
invoice_decoded.invoice_created_at.unwrap() + u64::from(e_at),
|
||||
)
|
||||
})
|
||||
}
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => invoice_decoded
|
||||
.expiry
|
||||
.map(|e_at| Timestamp::from_secs(invoice_decoded.created_at.unwrap() + e_at)),
|
||||
_ => continue,
|
||||
};
|
||||
let preimage = list_invoice
|
||||
.payment_preimage
|
||||
.map(|p| hex::encode(p.to_vec()));
|
||||
|
||||
let state = match list_invoice.status {
|
||||
ListinvoicesInvoicesStatus::PAID => nip47::TransactionState::Settled,
|
||||
ListinvoicesInvoicesStatus::EXPIRED => nip47::TransactionState::Expired,
|
||||
ListinvoicesInvoicesStatus::UNPAID => nip47::TransactionState::Pending,
|
||||
};
|
||||
|
||||
transactions.push(nip47::LookupInvoiceResponse {
|
||||
transaction_type: Some(nip47::TransactionType::Incoming),
|
||||
invoice: Some(invstring),
|
||||
description,
|
||||
description_hash,
|
||||
preimage,
|
||||
payment_hash: list_invoice.payment_hash.to_string(),
|
||||
amount,
|
||||
fees_paid: 0,
|
||||
created_at,
|
||||
expires_at,
|
||||
settled_at: list_invoice.paid_at.map(Timestamp::from_secs),
|
||||
metadata: None,
|
||||
state: Some(state),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -443,126 +163,239 @@ pub async fn list_transactions(
|
|||
.pays;
|
||||
|
||||
for list_pay in list_pays {
|
||||
let invstring = if list_pay.bolt11.is_some() {
|
||||
list_pay.bolt11
|
||||
} else {
|
||||
list_pay.bolt12
|
||||
};
|
||||
|
||||
let invoice_decoded = if let Some(invstr) = &invstring {
|
||||
Some(
|
||||
rpc.call_typed(&DecodeRequest {
|
||||
string: invstr.clone(),
|
||||
})
|
||||
.await
|
||||
.map_err(|e| nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Internal,
|
||||
message: e.to_string(),
|
||||
})?,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if invoice_decoded.is_some() && !invoice_decoded.as_ref().unwrap().valid {
|
||||
continue;
|
||||
match make_lookup_response_from_listpays(&mut rpc, list_pay).await {
|
||||
Ok(t) => transactions.push(t),
|
||||
Err(_e) => (),
|
||||
}
|
||||
|
||||
let description_hash = if let Some(inv_dec) = &invoice_decoded {
|
||||
match inv_dec.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => None,
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
inv_dec.description_hash.map(|h| h.to_string())
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let amount = if let Some(amt) = list_pay.amount_msat {
|
||||
amt.msat()
|
||||
} else if let Some(inv_dec) = &invoice_decoded {
|
||||
match inv_dec.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
|
||||
inv_dec.invoice_amount_msat.unwrap().msat()
|
||||
}
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
if let Some(amt) = inv_dec.amount_msat {
|
||||
amt.msat()
|
||||
} else {
|
||||
// amount: `any` but have to put a value...
|
||||
0
|
||||
}
|
||||
}
|
||||
_ => continue,
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let description = if let Some(inv_dec) = invoice_decoded {
|
||||
match inv_dec.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
|
||||
inv_dec.offer_description
|
||||
}
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => inv_dec.description,
|
||||
_ => continue,
|
||||
}
|
||||
} else {
|
||||
list_pay.description
|
||||
};
|
||||
|
||||
let fees_paid = if let Some(amt_sent) = list_pay.amount_sent_msat {
|
||||
amt_sent.msat() - amount
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let preimage = list_pay.preimage.map(|p| hex::encode(p.to_vec()));
|
||||
|
||||
let state = match list_pay.status {
|
||||
ListpaysPaysStatus::COMPLETE => nip47::TransactionState::Settled,
|
||||
ListpaysPaysStatus::FAILED => nip47::TransactionState::Failed,
|
||||
ListpaysPaysStatus::PENDING => nip47::TransactionState::Pending,
|
||||
};
|
||||
|
||||
transactions.push(nip47::LookupInvoiceResponse {
|
||||
transaction_type: Some(nip47::TransactionType::Outgoing),
|
||||
invoice: invstring,
|
||||
description,
|
||||
description_hash,
|
||||
preimage,
|
||||
payment_hash: list_pay.payment_hash.to_string(),
|
||||
amount,
|
||||
fees_paid,
|
||||
created_at: Timestamp::from_secs(list_pay.created_at),
|
||||
expires_at: None,
|
||||
settled_at: list_pay.completed_at.map(Timestamp::from_secs),
|
||||
metadata: None,
|
||||
state: Some(state),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
transactions.sort_by_key(|t| Reverse(t.created_at));
|
||||
|
||||
if let Some(off) = params.offset.map(|o| o as usize) {
|
||||
if off < transactions.len() {
|
||||
transactions.drain(0..off);
|
||||
} else {
|
||||
if let Some(offset) = params.offset {
|
||||
let len = transactions.len() as u64;
|
||||
if offset >= len {
|
||||
transactions.clear();
|
||||
} else {
|
||||
let off = usize::try_from(offset).unwrap();
|
||||
transactions.drain(0..off);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(l) = params.limit {
|
||||
if transactions.len() > (l as usize) {
|
||||
transactions = transactions.drain(0..(l as usize)).collect();
|
||||
if let Some(limit) = params.limit {
|
||||
let len = transactions.len() as u64;
|
||||
if limit < len {
|
||||
let l = usize::try_from(limit).unwrap();
|
||||
transactions = transactions.drain(0..l).collect();
|
||||
}
|
||||
}
|
||||
|
||||
transactions = trim_to_size(transactions, 127 * 1024);
|
||||
|
||||
Ok(transactions)
|
||||
}
|
||||
|
||||
async fn make_lookup_response_from_listinvoices(
|
||||
rpc: &mut ClnRpc,
|
||||
list_invoice: ListinvoicesInvoices,
|
||||
) -> Result<nip47::LookupInvoiceResponse, nip47::NIP47Error> {
|
||||
let not_invoice_err = Err(nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Other,
|
||||
message: NOT_INV_ERR.to_owned(),
|
||||
});
|
||||
|
||||
let invstring = if list_invoice.bolt11.is_some() {
|
||||
list_invoice.bolt11.as_ref().unwrap()
|
||||
} else {
|
||||
list_invoice.bolt12.as_ref().unwrap()
|
||||
};
|
||||
let invoice_decoded = rpc
|
||||
.call_typed(&DecodeRequest {
|
||||
string: invstring.clone(),
|
||||
})
|
||||
.await
|
||||
.map_err(|e| nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Internal,
|
||||
message: e.to_string(),
|
||||
})?;
|
||||
|
||||
if !invoice_decoded.valid {
|
||||
return not_invoice_err;
|
||||
}
|
||||
|
||||
let description = match invoice_decoded.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => invoice_decoded.offer_description,
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => invoice_decoded.description,
|
||||
_ => return not_invoice_err,
|
||||
};
|
||||
let description_hash = match invoice_decoded.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => None,
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
invoice_decoded.description_hash.map(|h| h.to_string())
|
||||
}
|
||||
_ => return not_invoice_err,
|
||||
};
|
||||
|
||||
let amount = match invoice_decoded.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
|
||||
invoice_decoded.invoice_amount_msat.unwrap().msat()
|
||||
}
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
if let Some(amt) = invoice_decoded.amount_msat {
|
||||
amt.msat()
|
||||
} else if let Some(a) = list_invoice.amount_msat {
|
||||
a.msat()
|
||||
} else {
|
||||
// amount: `any` but have to put a value...
|
||||
0
|
||||
}
|
||||
}
|
||||
_ => return not_invoice_err,
|
||||
};
|
||||
|
||||
let created_at = match invoice_decoded.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
|
||||
Timestamp::from_secs(invoice_decoded.invoice_created_at.unwrap())
|
||||
}
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
Timestamp::from_secs(invoice_decoded.created_at.unwrap())
|
||||
}
|
||||
_ => return not_invoice_err,
|
||||
};
|
||||
|
||||
let preimage = list_invoice
|
||||
.payment_preimage
|
||||
.map(|p| hex::encode(p.to_vec()));
|
||||
|
||||
let state = match list_invoice.status {
|
||||
ListinvoicesInvoicesStatus::UNPAID => nip47::TransactionState::Pending,
|
||||
ListinvoicesInvoicesStatus::PAID => nip47::TransactionState::Settled,
|
||||
ListinvoicesInvoicesStatus::EXPIRED => nip47::TransactionState::Expired,
|
||||
};
|
||||
|
||||
Ok(nip47::LookupInvoiceResponse {
|
||||
transaction_type: Some(nip47::TransactionType::Incoming),
|
||||
invoice: Some(invstring.to_owned()),
|
||||
description,
|
||||
description_hash,
|
||||
preimage,
|
||||
payment_hash: list_invoice.payment_hash.to_string(),
|
||||
amount,
|
||||
fees_paid: 0,
|
||||
created_at,
|
||||
expires_at: Some(Timestamp::from_secs(list_invoice.expires_at)),
|
||||
settled_at: list_invoice.paid_at.map(Timestamp::from_secs),
|
||||
metadata: None,
|
||||
state: Some(state),
|
||||
})
|
||||
}
|
||||
|
||||
async fn make_lookup_response_from_listpays(
|
||||
rpc: &mut ClnRpc,
|
||||
list_pay: ListpaysPays,
|
||||
) -> Result<nip47::LookupInvoiceResponse, nip47::NIP47Error> {
|
||||
let not_invoice_err = Err(nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Other,
|
||||
message: NOT_INV_ERR.to_owned(),
|
||||
});
|
||||
|
||||
let invstring = if list_pay.bolt11.is_some() {
|
||||
list_pay.bolt11
|
||||
} else {
|
||||
list_pay.bolt12
|
||||
};
|
||||
|
||||
let invoice_decoded = if let Some(invstr) = &invstring {
|
||||
Some(
|
||||
rpc.call_typed(&DecodeRequest {
|
||||
string: invstr.clone(),
|
||||
})
|
||||
.await
|
||||
.map_err(|e| nip47::NIP47Error {
|
||||
code: nip47::ErrorCode::Internal,
|
||||
message: e.to_string(),
|
||||
})?,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if invoice_decoded.is_some() && !invoice_decoded.as_ref().unwrap().valid {
|
||||
return not_invoice_err;
|
||||
}
|
||||
|
||||
let description_hash = if let Some(inv_dec) = &invoice_decoded {
|
||||
match inv_dec.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => None,
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
inv_dec.description_hash.map(|h| h.to_string())
|
||||
}
|
||||
_ => return not_invoice_err,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let amount = if let Some(amt) = list_pay.amount_msat {
|
||||
amt.msat()
|
||||
} else if let Some(inv_dec) = &invoice_decoded {
|
||||
match inv_dec.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => {
|
||||
inv_dec.invoice_amount_msat.unwrap().msat()
|
||||
}
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => {
|
||||
if let Some(amt) = inv_dec.amount_msat {
|
||||
amt.msat()
|
||||
} else {
|
||||
// amount: `any` but have to put a value...
|
||||
0
|
||||
}
|
||||
}
|
||||
_ => return not_invoice_err,
|
||||
}
|
||||
} else {
|
||||
return not_invoice_err;
|
||||
};
|
||||
|
||||
let description = if let Some(inv_dec) = invoice_decoded {
|
||||
match inv_dec.item_type {
|
||||
cln_rpc::model::responses::DecodeType::BOLT12_INVOICE => inv_dec.offer_description,
|
||||
cln_rpc::model::responses::DecodeType::BOLT11_INVOICE => inv_dec.description,
|
||||
_ => return not_invoice_err,
|
||||
}
|
||||
} else {
|
||||
list_pay.description
|
||||
};
|
||||
|
||||
let fees_paid = if let Some(amt_sent) = list_pay.amount_sent_msat {
|
||||
amt_sent.msat() - amount
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let preimage = list_pay.preimage.map(|p| hex::encode(p.to_vec()));
|
||||
|
||||
let state = match list_pay.status {
|
||||
ListpaysPaysStatus::PENDING => nip47::TransactionState::Pending,
|
||||
ListpaysPaysStatus::FAILED => nip47::TransactionState::Failed,
|
||||
ListpaysPaysStatus::COMPLETE => nip47::TransactionState::Settled,
|
||||
};
|
||||
|
||||
Ok(nip47::LookupInvoiceResponse {
|
||||
transaction_type: Some(nip47::TransactionType::Outgoing),
|
||||
invoice: invstring,
|
||||
description,
|
||||
description_hash,
|
||||
preimage,
|
||||
payment_hash: list_pay.payment_hash.to_string(),
|
||||
amount,
|
||||
fees_paid,
|
||||
created_at: Timestamp::from_secs(list_pay.created_at),
|
||||
expires_at: None,
|
||||
settled_at: list_pay.completed_at.map(Timestamp::from_secs),
|
||||
metadata: None,
|
||||
state: Some(state),
|
||||
})
|
||||
}
|
||||
|
||||
fn trim_to_size(
|
||||
mut transactions: Vec<nip47::LookupInvoiceResponse>,
|
||||
max_size: usize,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ use parking_lot::Mutex;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::oneshot;
|
||||
|
||||
pub const NOT_INV_ERR: &str = "Not an invoice or invalid invoice";
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PluginState {
|
||||
pub config: Arc<Mutex<Config>>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue