Skip to content

Commit

Permalink
RawBolt11Invoice to/from ascii utilities
Browse files Browse the repository at this point in the history
for remote signing of invoices
  • Loading branch information
devrandom committed Jan 17, 2025
1 parent 3fbf97d commit 9011867
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion lightning-invoice/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ extern crate serde;
#[cfg(feature = "std")]
use std::time::SystemTime;

use bech32::primitives::decode::CheckedHrpstringError;
use bech32::primitives::decode::{CheckedHrpstringError, UncheckedHrpstring};
use bech32::Fe32;
use bitcoin::hashes::{sha256, Hash};
use bitcoin::{Address, Network, PubkeyHash, ScriptHash, WitnessProgram, WitnessVersion};
Expand Down Expand Up @@ -80,6 +80,10 @@ use crate::prelude::*;
pub use crate::de::FromBase32;
#[cfg(fuzzing)]
pub use crate::ser::Base32Iterable;
#[cfg(not(fuzzing))]
use crate::de::FromBase32;
#[cfg(not(fuzzing))]
use crate::ser::Base32Iterable;

/// Errors that indicate what is wrong with the invoice. They have some granularity for debug
/// reasons, but should generally result in an "invalid BOLT11 invoice" message for the user.
Expand Down Expand Up @@ -1189,6 +1193,31 @@ impl RawBolt11Invoice {
pub fn currency(&self) -> Currency {
self.hrp.currency.clone()
}

/// Convert to ascii bytes with HRP prefix and base32 encoded data part.
/// Can be used to transmit unsigned invoices for remote signing.
pub fn to_ascii(&self) -> Vec<u8> {
self.hrp.to_string().into_bytes().into_iter()
.chain(self.data.fe_iter().map(|e| e.to_char() as u8)).collect()
}

/// Convert from ascii bytes with HRP prefix and base32 encoded data part.
/// Can be used to receive unsigned invoices for remote signing.
pub fn from_ascii(s: &str) -> Result<Self, Bolt11ParseError> {
let parsed = UncheckedHrpstring::new(s)
.map_err(|_| Bolt11ParseError::MalformedHRP)?;
let hrp = parsed.hrp();
let raw_hrp: RawHrp = hrp.to_string().to_lowercase().parse()?;

let data = parsed.data_part_ascii().iter().map(|c| Fe32::from_char(*c as char)).collect::<Result<Vec<_>, _>>()
.map_err(|_| Bolt11ParseError::MalformedHRP)?;
let data_part = RawDataPart::from_base32(&data)?;

Ok(Self {
hrp: raw_hrp,
data: data_part,
})
}
}

impl PositiveTimestamp {
Expand Down

0 comments on commit 9011867

Please sign in to comment.