Skip to content

Commit

Permalink
feat(lnd-rest): add get_invoice for LndRest backend
Browse files Browse the repository at this point in the history
  • Loading branch information
Dolu89 committed Aug 17, 2022
1 parent e3876e6 commit 4d74513
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 8 deletions.
20 changes: 14 additions & 6 deletions core/src/backends/lnd/rest/node.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use crate::error::Error;
use crate::node::NodeMethods;
use crate::types::{CreateInvoiceParams, CreateInvoiceResult, Invoice, NodeConfig, NodeInfo};
use crate::types::{CreateInvoiceParams, CreateInvoiceResult, Invoice, NodeInfo};

use super::config::LndRestConfig;
use super::types::{ApiError, CreateInvoiceRequest, CreateInvoiceResponse, GetInfoResponse};
use super::types::{
ApiError, CreateInvoiceRequest, CreateInvoiceResponse, GetInfoResponse, InvoiceResponse,
};

pub struct LndRest {
config: LndRestConfig,
Expand Down Expand Up @@ -79,9 +81,15 @@ impl NodeMethods for LndRest {
Ok(data.into())
}

async fn get_invoice(&self, _payment_hash: String) -> Result<Invoice, Error> {
Err(Error::UnknownError(String::from(
"get_invoice() not implemented yet",
)))
async fn get_invoice(&self, payment_hash: String) -> Result<Invoice, Error> {
let url = format!("{0}/v1/invoice/{1}", self.config.url, payment_hash);

let mut response = self.client.get(&url).send().await?;

response = Self::on_response(response).await?;

let data: InvoiceResponse = response.json().await?;

Ok(data.try_into()?)
}
}
69 changes: 67 additions & 2 deletions core/src/backends/lnd/rest/types.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#![allow(clippy::from_over_into)]

use serde::{Deserialize, Serialize};
use std::collections::HashMap;

use crate::error::Error;
use crate::tools::convert_base64_to_hex;
use crate::types::*;
use crate::{error::Error, tools::parse_number};
use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize)]
pub struct ApiError {
Expand Down Expand Up @@ -131,3 +132,67 @@ impl Into<NodeInfo> for GetInfoResponse {
}
}
}

#[derive(Debug, Deserialize)]
pub struct InvoiceResponse {
memo: String,
r_preimage: String,
r_hash: String,
value: String,
value_msat: String,
settled: bool,
creation_date: String,
settle_date: String,
payment_request: String,
expiry: String,
state: InvoiceStateResponse,
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum InvoiceStateResponse {
Open,
Settled,
Cancelled,
Accepted,
}

impl TryInto<Invoice> for InvoiceResponse {
type Error = Error;

fn try_into(self) -> Result<Invoice, Error> {
let mut settle_date: Option<i64> = None;
if self.settled {
settle_date =
Some(parse_number(&self.settle_date).expect("settle_date should be a number"));
}

let status = match self.state {
InvoiceStateResponse::Open => crate::types::InvoiceStatus::Pending,
InvoiceStateResponse::Settled => crate::types::InvoiceStatus::Settled,
InvoiceStateResponse::Cancelled => crate::types::InvoiceStatus::Cancelled,
InvoiceStateResponse::Accepted => crate::types::InvoiceStatus::Accepted,
};

let invoice = Invoice {
bolt11: self.payment_request,
memo: self.memo,
amount: parse_number(&self.value).expect("amt_paid_sat should be a number"),
amount_msat: parse_number(&self.value_msat).expect("amt_paid_msat should be a number"),
pre_image: Some(
convert_base64_to_hex(&self.r_preimage)
.expect("coudln't convert r_preimage from base64 to hex"),
),
payment_hash: convert_base64_to_hex(&self.r_hash)
.expect("coudln't convert r_hash from base64 to hex"),
settled: self.settled,
settle_date,
creation_date: parse_number(&self.creation_date)
.expect("creation_date should be a number"),
expiry: parse_number(&self.expiry).expect("expiry should be a number"),
status,
};

Ok(invoice)
}
}
18 changes: 18 additions & 0 deletions core/src/tools.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
use std::str::FromStr;

use crate::error::Error;

pub fn sat_to_msat(sat: &u64) -> u64 {
sat * 1000
}

pub fn msat_to_sat(msat: &u64) -> u64 {
msat / 1000
}

pub fn convert_base64_to_hex(hex: &str) -> Result<String, Error> {
let base64_decoded = base64::decode(hex);
match base64_decoded {
Ok(e) => Ok(hex::encode(e)),
Err(_) => Err(Error::ConversionError(String::from(
"coudln't convert from base64 to hex",
))),
}
}

pub fn parse_number<T: FromStr>(text: &str) -> Result<T, T::Err> {
text.trim().parse::<T>()
}

0 comments on commit 4d74513

Please sign in to comment.