Merge pull request #60 from TheBlueMatt/main
[ldk-c-bindings] / lightning-c-bindings / src / lightning_invoice / mod.rs
index 53314331cf26b146aa5665b794bb1808cf1d2822..760da327713da2aafe6e3373e88ee873391703c9 100644 (file)
 //!   * For constructing invoices use the `InvoiceBuilder`
 //!   * For serializing invoices use the `Display`/`ToString` traits
 
-use std::str::FromStr;
-use std::ffi::c_void;
+use alloc::str::FromStr;
+use core::ffi::c_void;
 use core::convert::Infallible;
 use bitcoin::hashes::Hash;
 use crate::c_types::*;
+#[cfg(feature="no-std")]
+use alloc::{vec::Vec, boxed::Box};
 
 pub mod payment;
 pub mod utils;
 pub mod constants;
 mod de {
 
-use std::str::FromStr;
-use std::ffi::c_void;
+use alloc::str::FromStr;
+use core::ffi::c_void;
 use core::convert::Infallible;
 use bitcoin::hashes::Hash;
 use crate::c_types::*;
+#[cfg(feature="no-std")]
+use alloc::{vec::Vec, boxed::Box};
 
 mod hrp_sm {
 
-use std::str::FromStr;
-use std::ffi::c_void;
+use alloc::str::FromStr;
+use core::ffi::c_void;
 use core::convert::Infallible;
 use bitcoin::hashes::Hash;
 use crate::c_types::*;
+#[cfg(feature="no-std")]
+use alloc::{vec::Vec, boxed::Box};
 
 }
 #[no_mangle]
@@ -80,45 +86,77 @@ pub extern "C" fn SignedRawInvoice_from_str(s: crate::c_types::Str) -> crate::c_
 }
 mod ser {
 
-use std::str::FromStr;
-use std::ffi::c_void;
+use alloc::str::FromStr;
+use core::ffi::c_void;
 use core::convert::Infallible;
 use bitcoin::hashes::Hash;
 use crate::c_types::*;
+#[cfg(feature="no-std")]
+use alloc::{vec::Vec, boxed::Box};
 
 #[no_mangle]
 /// Get the string representation of a Invoice object
 pub extern "C" fn Invoice_to_str(o: &crate::lightning_invoice::Invoice) -> Str {
-       format!("{}", o.get_native_ref()).into()
+       alloc::format!("{}", o.get_native_ref()).into()
 }
 #[no_mangle]
 /// Get the string representation of a SignedRawInvoice object
 pub extern "C" fn SignedRawInvoice_to_str(o: &crate::lightning_invoice::SignedRawInvoice) -> Str {
-       format!("{}", o.get_native_ref()).into()
+       alloc::format!("{}", o.get_native_ref()).into()
 }
 #[no_mangle]
 /// Get the string representation of a Currency object
 pub extern "C" fn Currency_to_str(o: &crate::lightning_invoice::Currency) -> Str {
-       format!("{}", &o.to_native()).into()
+       alloc::format!("{}", &o.to_native()).into()
 }
 #[no_mangle]
 /// Get the string representation of a SiPrefix object
 pub extern "C" fn SiPrefix_to_str(o: &crate::lightning_invoice::SiPrefix) -> Str {
-       format!("{}", &o.to_native()).into()
+       alloc::format!("{}", &o.to_native()).into()
 }
 }
 mod tb {
 
-use std::str::FromStr;
-use std::ffi::c_void;
+use alloc::str::FromStr;
+use core::ffi::c_void;
 use core::convert::Infallible;
 use bitcoin::hashes::Hash;
 use crate::c_types::*;
+#[cfg(feature="no-std")]
+use alloc::{vec::Vec, boxed::Box};
 
 }
+mod prelude {
+
+use alloc::str::FromStr;
+use core::ffi::c_void;
+use core::convert::Infallible;
+use bitcoin::hashes::Hash;
+use crate::c_types::*;
+#[cfg(feature="no-std")]
+use alloc::{vec::Vec, boxed::Box};
+
+}
+mod sync {
+
+use alloc::str::FromStr;
+use core::ffi::c_void;
+use core::convert::Infallible;
+use bitcoin::hashes::Hash;
+use crate::c_types::*;
+#[cfg(feature="no-std")]
+use alloc::{vec::Vec, boxed::Box};
+
+}
+/// The maximum timestamp as [`Duration::as_secs`] since the Unix epoch allowed by [`BOLT 11`].
+///
+/// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
+
+#[no_mangle]
+pub static MAX_TIMESTAMP: u64 = lightning_invoice::MAX_TIMESTAMP;
 /// Default expiry time as defined by [BOLT 11].
 ///
-/// [BOLT 11]: https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md
+/// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
 
 #[no_mangle]
 pub static DEFAULT_EXPIRY_TIME: u64 = lightning_invoice::DEFAULT_EXPIRY_TIME;
@@ -127,29 +165,11 @@ pub static DEFAULT_EXPIRY_TIME: u64 = lightning_invoice::DEFAULT_EXPIRY_TIME;
 /// Note that this is *not* the same value as rust-lightning's minimum CLTV expiry, which is
 /// provided in [`MIN_FINAL_CLTV_EXPIRY`].
 ///
-/// [BOLT 11]: https://github.com/lightningnetwork/lightning-rfc/blob/master/11-payment-encoding.md
+/// [BOLT 11]: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md
 /// [`MIN_FINAL_CLTV_EXPIRY`]: lightning::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY
 
 #[no_mangle]
 pub static DEFAULT_MIN_FINAL_CLTV_EXPIRY: u64 = lightning_invoice::DEFAULT_MIN_FINAL_CLTV_EXPIRY;
-/// **Call this function on startup to ensure that all assumptions about the platform are valid.**
-///
-/// Unfortunately we have to make assumptions about the upper bounds of the `SystemTime` type on
-/// your platform which we can't fully verify at compile time and which isn't part of it's contract.
-/// To our best knowledge our assumptions hold for all platforms officially supported by rust, but
-/// since this check is fast we recommend to do it anyway.
-///
-/// If this function fails this is considered a bug. Please open an issue describing your
-/// platform and stating your current system time.
-///
-/// # Panics
-/// If the check fails this function panics. By calling this function on startup you ensure that
-/// this wont happen at an arbitrary later point in time.
-#[no_mangle]
-pub extern "C" fn check_platform() {
-       lightning_invoice::check_platform()
-}
-
 
 use lightning_invoice::Invoice as nativeInvoiceImport;
 pub(crate) type nativeInvoice = nativeInvoiceImport;
@@ -202,7 +222,7 @@ impl Invoice {
        pub(crate) fn take_inner(mut self) -> *mut nativeInvoice {
                assert!(self.is_owned);
                let ret = ObjOps::untweak_ptr(self.inner);
-               self.inner = std::ptr::null_mut();
+               self.inner = core::ptr::null_mut();
                ret
        }
 }
@@ -218,7 +238,7 @@ pub extern "C" fn Invoice_eq(a: &Invoice, b: &Invoice) -> bool {
 impl Clone for Invoice {
        fn clone(&self) -> Self {
                Self {
-                       inner: if <*mut nativeInvoice>::is_null(self.inner) { std::ptr::null_mut() } else {
+                       inner: if <*mut nativeInvoice>::is_null(self.inner) { core::ptr::null_mut() } else {
                                ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) },
                        is_owned: true,
                }
@@ -285,7 +305,7 @@ impl SignedRawInvoice {
        pub(crate) fn take_inner(mut self) -> *mut nativeSignedRawInvoice {
                assert!(self.is_owned);
                let ret = ObjOps::untweak_ptr(self.inner);
-               self.inner = std::ptr::null_mut();
+               self.inner = core::ptr::null_mut();
                ret
        }
 }
@@ -301,7 +321,7 @@ pub extern "C" fn SignedRawInvoice_eq(a: &SignedRawInvoice, b: &SignedRawInvoice
 impl Clone for SignedRawInvoice {
        fn clone(&self) -> Self {
                Self {
-                       inner: if <*mut nativeSignedRawInvoice>::is_null(self.inner) { std::ptr::null_mut() } else {
+                       inner: if <*mut nativeSignedRawInvoice>::is_null(self.inner) { core::ptr::null_mut() } else {
                                ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) },
                        is_owned: true,
                }
@@ -368,7 +388,7 @@ impl RawInvoice {
        pub(crate) fn take_inner(mut self) -> *mut nativeRawInvoice {
                assert!(self.is_owned);
                let ret = ObjOps::untweak_ptr(self.inner);
-               self.inner = std::ptr::null_mut();
+               self.inner = core::ptr::null_mut();
                ret
        }
 }
@@ -395,7 +415,7 @@ pub extern "C" fn RawInvoice_eq(a: &RawInvoice, b: &RawInvoice) -> bool {
 impl Clone for RawInvoice {
        fn clone(&self) -> Self {
                Self {
-                       inner: if <*mut nativeRawInvoice>::is_null(self.inner) { std::ptr::null_mut() } else {
+                       inner: if <*mut nativeRawInvoice>::is_null(self.inner) { core::ptr::null_mut() } else {
                                ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) },
                        is_owned: true,
                }
@@ -458,7 +478,7 @@ impl RawDataPart {
        pub(crate) fn take_inner(mut self) -> *mut nativeRawDataPart {
                assert!(self.is_owned);
                let ret = ObjOps::untweak_ptr(self.inner);
-               self.inner = std::ptr::null_mut();
+               self.inner = core::ptr::null_mut();
                ret
        }
 }
@@ -485,7 +505,7 @@ pub extern "C" fn RawDataPart_eq(a: &RawDataPart, b: &RawDataPart) -> bool {
 impl Clone for RawDataPart {
        fn clone(&self) -> Self {
                Self {
-                       inner: if <*mut nativeRawDataPart>::is_null(self.inner) { std::ptr::null_mut() } else {
+                       inner: if <*mut nativeRawDataPart>::is_null(self.inner) { core::ptr::null_mut() } else {
                                ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) },
                        is_owned: true,
                }
@@ -505,12 +525,12 @@ pub extern "C" fn RawDataPart_clone(orig: &RawDataPart) -> RawDataPart {
 use lightning_invoice::PositiveTimestamp as nativePositiveTimestampImport;
 pub(crate) type nativePositiveTimestamp = nativePositiveTimestampImport;
 
-/// A timestamp that refers to a date after 1 January 1970 which means its representation as UNIX
-/// timestamp is positive.
+/// A timestamp that refers to a date after 1 January 1970.
 ///
 /// # Invariants
-/// The UNIX timestamp representing the stored time has to be positive and small enough so that
-/// a `EpiryTime` can be added to it without an overflow.
+///
+/// The Unix timestamp representing the stored time has to be positive and no greater than
+/// [`MAX_TIMESTAMP`].
 #[must_use]
 #[repr(C)]
 pub struct PositiveTimestamp {
@@ -553,7 +573,7 @@ impl PositiveTimestamp {
        pub(crate) fn take_inner(mut self) -> *mut nativePositiveTimestamp {
                assert!(self.is_owned);
                let ret = ObjOps::untweak_ptr(self.inner);
-               self.inner = std::ptr::null_mut();
+               self.inner = core::ptr::null_mut();
                ret
        }
 }
@@ -569,7 +589,7 @@ pub extern "C" fn PositiveTimestamp_eq(a: &PositiveTimestamp, b: &PositiveTimest
 impl Clone for PositiveTimestamp {
        fn clone(&self) -> Self {
                Self {
-                       inner: if <*mut nativePositiveTimestamp>::is_null(self.inner) { std::ptr::null_mut() } else {
+                       inner: if <*mut nativePositiveTimestamp>::is_null(self.inner) { core::ptr::null_mut() } else {
                                ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) },
                        is_owned: true,
                }
@@ -761,11 +781,11 @@ pub extern "C" fn Currency_signet() -> Currency {
 /// Checks if two Currencys contain equal inner contents.
 #[no_mangle]
 pub extern "C" fn Currency_hash(o: &Currency) -> u64 {
-       // Note that we'd love to use std::collections::hash_map::DefaultHasher but it's not in core
+       // Note that we'd love to use alloc::collections::hash_map::DefaultHasher but it's not in core
        #[allow(deprecated)]
        let mut hasher = core::hash::SipHasher::new();
-       std::hash::Hash::hash(&o.to_native(), &mut hasher);
-       std::hash::Hasher::finish(&hasher)
+       core::hash::Hash::hash(&o.to_native(), &mut hasher);
+       core::hash::Hasher::finish(&hasher)
 }
 /// Checks if two Currencys contain equal inner contents.
 /// This ignores pointers and is_owned flags and looks at the values in fields.
@@ -820,14 +840,14 @@ impl Sha256 {
        pub(crate) fn take_inner(mut self) -> *mut nativeSha256 {
                assert!(self.is_owned);
                let ret = ObjOps::untweak_ptr(self.inner);
-               self.inner = std::ptr::null_mut();
+               self.inner = core::ptr::null_mut();
                ret
        }
 }
 impl Clone for Sha256 {
        fn clone(&self) -> Self {
                Self {
-                       inner: if <*mut nativeSha256>::is_null(self.inner) { std::ptr::null_mut() } else {
+                       inner: if <*mut nativeSha256>::is_null(self.inner) { core::ptr::null_mut() } else {
                                ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) },
                        is_owned: true,
                }
@@ -847,11 +867,11 @@ pub extern "C" fn Sha256_clone(orig: &Sha256) -> Sha256 {
 #[no_mangle]
 pub extern "C" fn Sha256_hash(o: &Sha256) -> u64 {
        if o.inner.is_null() { return 0; }
-       // Note that we'd love to use std::collections::hash_map::DefaultHasher but it's not in core
+       // Note that we'd love to use alloc::collections::hash_map::DefaultHasher but it's not in core
        #[allow(deprecated)]
        let mut hasher = core::hash::SipHasher::new();
-       std::hash::Hash::hash(o.get_native_ref(), &mut hasher);
-       std::hash::Hasher::finish(&hasher)
+       core::hash::Hash::hash(o.get_native_ref(), &mut hasher);
+       core::hash::Hasher::finish(&hasher)
 }
 /// Checks if two Sha256s contain equal inner contents.
 /// This ignores pointers and is_owned flags and looks at the values in fields.
@@ -912,14 +932,14 @@ impl Description {
        pub(crate) fn take_inner(mut self) -> *mut nativeDescription {
                assert!(self.is_owned);
                let ret = ObjOps::untweak_ptr(self.inner);
-               self.inner = std::ptr::null_mut();
+               self.inner = core::ptr::null_mut();
                ret
        }
 }
 impl Clone for Description {
        fn clone(&self) -> Self {
                Self {
-                       inner: if <*mut nativeDescription>::is_null(self.inner) { std::ptr::null_mut() } else {
+                       inner: if <*mut nativeDescription>::is_null(self.inner) { core::ptr::null_mut() } else {
                                ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) },
                        is_owned: true,
                }
@@ -939,11 +959,11 @@ pub extern "C" fn Description_clone(orig: &Description) -> Description {
 #[no_mangle]
 pub extern "C" fn Description_hash(o: &Description) -> u64 {
        if o.inner.is_null() { return 0; }
-       // Note that we'd love to use std::collections::hash_map::DefaultHasher but it's not in core
+       // Note that we'd love to use alloc::collections::hash_map::DefaultHasher but it's not in core
        #[allow(deprecated)]
        let mut hasher = core::hash::SipHasher::new();
-       std::hash::Hash::hash(o.get_native_ref(), &mut hasher);
-       std::hash::Hasher::finish(&hasher)
+       core::hash::Hash::hash(o.get_native_ref(), &mut hasher);
+       core::hash::Hasher::finish(&hasher)
 }
 /// Checks if two Descriptions contain equal inner contents.
 /// This ignores pointers and is_owned flags and looks at the values in fields.
@@ -1001,7 +1021,7 @@ impl PayeePubKey {
        pub(crate) fn take_inner(mut self) -> *mut nativePayeePubKey {
                assert!(self.is_owned);
                let ret = ObjOps::untweak_ptr(self.inner);
-               self.inner = std::ptr::null_mut();
+               self.inner = core::ptr::null_mut();
                ret
        }
 }
@@ -1025,7 +1045,7 @@ pub extern "C" fn PayeePubKey_new(mut a_arg: crate::c_types::PublicKey) -> Payee
 impl Clone for PayeePubKey {
        fn clone(&self) -> Self {
                Self {
-                       inner: if <*mut nativePayeePubKey>::is_null(self.inner) { std::ptr::null_mut() } else {
+                       inner: if <*mut nativePayeePubKey>::is_null(self.inner) { core::ptr::null_mut() } else {
                                ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) },
                        is_owned: true,
                }
@@ -1045,11 +1065,11 @@ pub extern "C" fn PayeePubKey_clone(orig: &PayeePubKey) -> PayeePubKey {
 #[no_mangle]
 pub extern "C" fn PayeePubKey_hash(o: &PayeePubKey) -> u64 {
        if o.inner.is_null() { return 0; }
-       // Note that we'd love to use std::collections::hash_map::DefaultHasher but it's not in core
+       // Note that we'd love to use alloc::collections::hash_map::DefaultHasher but it's not in core
        #[allow(deprecated)]
        let mut hasher = core::hash::SipHasher::new();
-       std::hash::Hash::hash(o.get_native_ref(), &mut hasher);
-       std::hash::Hasher::finish(&hasher)
+       core::hash::Hash::hash(o.get_native_ref(), &mut hasher);
+       core::hash::Hasher::finish(&hasher)
 }
 /// Checks if two PayeePubKeys contain equal inner contents.
 /// This ignores pointers and is_owned flags and looks at the values in fields.
@@ -1066,11 +1086,6 @@ pub(crate) type nativeExpiryTime = nativeExpiryTimeImport;
 
 /// Positive duration that defines when (relatively to the timestamp) in the future the invoice
 /// expires
-///
-/// # Invariants
-/// The number of seconds this expiry time represents has to be in the range
-/// `0...(SYSTEM_TIME_MAX_UNIX_TIMESTAMP - MAX_EXPIRY_TIME)` to avoid overflows when adding it to a
-/// timestamp
 #[must_use]
 #[repr(C)]
 pub struct ExpiryTime {
@@ -1113,14 +1128,14 @@ impl ExpiryTime {
        pub(crate) fn take_inner(mut self) -> *mut nativeExpiryTime {
                assert!(self.is_owned);
                let ret = ObjOps::untweak_ptr(self.inner);
-               self.inner = std::ptr::null_mut();
+               self.inner = core::ptr::null_mut();
                ret
        }
 }
 impl Clone for ExpiryTime {
        fn clone(&self) -> Self {
                Self {
-                       inner: if <*mut nativeExpiryTime>::is_null(self.inner) { std::ptr::null_mut() } else {
+                       inner: if <*mut nativeExpiryTime>::is_null(self.inner) { core::ptr::null_mut() } else {
                                ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) },
                        is_owned: true,
                }
@@ -1140,11 +1155,11 @@ pub extern "C" fn ExpiryTime_clone(orig: &ExpiryTime) -> ExpiryTime {
 #[no_mangle]
 pub extern "C" fn ExpiryTime_hash(o: &ExpiryTime) -> u64 {
        if o.inner.is_null() { return 0; }
-       // Note that we'd love to use std::collections::hash_map::DefaultHasher but it's not in core
+       // Note that we'd love to use alloc::collections::hash_map::DefaultHasher but it's not in core
        #[allow(deprecated)]
        let mut hasher = core::hash::SipHasher::new();
-       std::hash::Hash::hash(o.get_native_ref(), &mut hasher);
-       std::hash::Hasher::finish(&hasher)
+       core::hash::Hash::hash(o.get_native_ref(), &mut hasher);
+       core::hash::Hasher::finish(&hasher)
 }
 /// Checks if two ExpiryTimes contain equal inner contents.
 /// This ignores pointers and is_owned flags and looks at the values in fields.
@@ -1202,7 +1217,7 @@ impl MinFinalCltvExpiry {
        pub(crate) fn take_inner(mut self) -> *mut nativeMinFinalCltvExpiry {
                assert!(self.is_owned);
                let ret = ObjOps::untweak_ptr(self.inner);
-               self.inner = std::ptr::null_mut();
+               self.inner = core::ptr::null_mut();
                ret
        }
 }
@@ -1226,7 +1241,7 @@ pub extern "C" fn MinFinalCltvExpiry_new(mut a_arg: u64) -> MinFinalCltvExpiry {
 impl Clone for MinFinalCltvExpiry {
        fn clone(&self) -> Self {
                Self {
-                       inner: if <*mut nativeMinFinalCltvExpiry>::is_null(self.inner) { std::ptr::null_mut() } else {
+                       inner: if <*mut nativeMinFinalCltvExpiry>::is_null(self.inner) { core::ptr::null_mut() } else {
                                ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) },
                        is_owned: true,
                }
@@ -1246,11 +1261,11 @@ pub extern "C" fn MinFinalCltvExpiry_clone(orig: &MinFinalCltvExpiry) -> MinFina
 #[no_mangle]
 pub extern "C" fn MinFinalCltvExpiry_hash(o: &MinFinalCltvExpiry) -> u64 {
        if o.inner.is_null() { return 0; }
-       // Note that we'd love to use std::collections::hash_map::DefaultHasher but it's not in core
+       // Note that we'd love to use alloc::collections::hash_map::DefaultHasher but it's not in core
        #[allow(deprecated)]
        let mut hasher = core::hash::SipHasher::new();
-       std::hash::Hash::hash(o.get_native_ref(), &mut hasher);
-       std::hash::Hasher::finish(&hasher)
+       core::hash::Hash::hash(o.get_native_ref(), &mut hasher);
+       core::hash::Hasher::finish(&hasher)
 }
 /// Checks if two MinFinalCltvExpirys contain equal inner contents.
 /// This ignores pointers and is_owned flags and looks at the values in fields.
@@ -1401,11 +1416,11 @@ pub extern "C" fn Fallback_script_hash(a: crate::c_types::TwentyBytes) -> Fallba
 /// Checks if two Fallbacks contain equal inner contents.
 #[no_mangle]
 pub extern "C" fn Fallback_hash(o: &Fallback) -> u64 {
-       // Note that we'd love to use std::collections::hash_map::DefaultHasher but it's not in core
+       // Note that we'd love to use alloc::collections::hash_map::DefaultHasher but it's not in core
        #[allow(deprecated)]
        let mut hasher = core::hash::SipHasher::new();
-       std::hash::Hash::hash(&o.to_native(), &mut hasher);
-       std::hash::Hasher::finish(&hasher)
+       core::hash::Hash::hash(&o.to_native(), &mut hasher);
+       core::hash::Hasher::finish(&hasher)
 }
 /// Checks if two Fallbacks contain equal inner contents.
 /// This ignores pointers and is_owned flags and looks at the values in fields.
@@ -1460,14 +1475,14 @@ impl InvoiceSignature {
        pub(crate) fn take_inner(mut self) -> *mut nativeInvoiceSignature {
                assert!(self.is_owned);
                let ret = ObjOps::untweak_ptr(self.inner);
-               self.inner = std::ptr::null_mut();
+               self.inner = core::ptr::null_mut();
                ret
        }
 }
 impl Clone for InvoiceSignature {
        fn clone(&self) -> Self {
                Self {
-                       inner: if <*mut nativeInvoiceSignature>::is_null(self.inner) { std::ptr::null_mut() } else {
+                       inner: if <*mut nativeInvoiceSignature>::is_null(self.inner) { core::ptr::null_mut() } else {
                                ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) },
                        is_owned: true,
                }
@@ -1543,14 +1558,14 @@ impl PrivateRoute {
        pub(crate) fn take_inner(mut self) -> *mut nativePrivateRoute {
                assert!(self.is_owned);
                let ret = ObjOps::untweak_ptr(self.inner);
-               self.inner = std::ptr::null_mut();
+               self.inner = core::ptr::null_mut();
                ret
        }
 }
 impl Clone for PrivateRoute {
        fn clone(&self) -> Self {
                Self {
-                       inner: if <*mut nativePrivateRoute>::is_null(self.inner) { std::ptr::null_mut() } else {
+                       inner: if <*mut nativePrivateRoute>::is_null(self.inner) { core::ptr::null_mut() } else {
                                ObjOps::heap_alloc(unsafe { &*ObjOps::untweak_ptr(self.inner) }.clone()) },
                        is_owned: true,
                }
@@ -1570,11 +1585,11 @@ pub extern "C" fn PrivateRoute_clone(orig: &PrivateRoute) -> PrivateRoute {
 #[no_mangle]
 pub extern "C" fn PrivateRoute_hash(o: &PrivateRoute) -> u64 {
        if o.inner.is_null() { return 0; }
-       // Note that we'd love to use std::collections::hash_map::DefaultHasher but it's not in core
+       // Note that we'd love to use alloc::collections::hash_map::DefaultHasher but it's not in core
        #[allow(deprecated)]
        let mut hasher = core::hash::SipHasher::new();
-       std::hash::Hash::hash(o.get_native_ref(), &mut hasher);
-       std::hash::Hasher::finish(&hasher)
+       core::hash::Hash::hash(o.get_native_ref(), &mut hasher);
+       core::hash::Hasher::finish(&hasher)
 }
 /// Checks if two PrivateRoutes contain equal inner contents.
 /// This ignores pointers and is_owned flags and looks at the values in fields.
@@ -1653,7 +1668,7 @@ pub extern "C" fn RawInvoice_hash(this_arg: &RawInvoice) -> crate::c_types::Thir
 #[no_mangle]
 pub extern "C" fn RawInvoice_payment_hash(this_arg: &RawInvoice) -> crate::lightning_invoice::Sha256 {
        let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.payment_hash();
-       let mut local_ret = crate::lightning_invoice::Sha256 { inner: unsafe { (if ret.is_none() { std::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning_invoice::Sha256<>) as *mut _ }, is_owned: false };
+       let mut local_ret = crate::lightning_invoice::Sha256 { inner: unsafe { (if ret.is_none() { core::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning_invoice::Sha256<>) as *mut _ }, is_owned: false };
        local_ret
 }
 
@@ -1663,7 +1678,7 @@ pub extern "C" fn RawInvoice_payment_hash(this_arg: &RawInvoice) -> crate::light
 #[no_mangle]
 pub extern "C" fn RawInvoice_description(this_arg: &RawInvoice) -> crate::lightning_invoice::Description {
        let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.description();
-       let mut local_ret = crate::lightning_invoice::Description { inner: unsafe { (if ret.is_none() { std::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning_invoice::Description<>) as *mut _ }, is_owned: false };
+       let mut local_ret = crate::lightning_invoice::Description { inner: unsafe { (if ret.is_none() { core::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning_invoice::Description<>) as *mut _ }, is_owned: false };
        local_ret
 }
 
@@ -1673,7 +1688,7 @@ pub extern "C" fn RawInvoice_description(this_arg: &RawInvoice) -> crate::lightn
 #[no_mangle]
 pub extern "C" fn RawInvoice_payee_pub_key(this_arg: &RawInvoice) -> crate::lightning_invoice::PayeePubKey {
        let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.payee_pub_key();
-       let mut local_ret = crate::lightning_invoice::PayeePubKey { inner: unsafe { (if ret.is_none() { std::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning_invoice::PayeePubKey<>) as *mut _ }, is_owned: false };
+       let mut local_ret = crate::lightning_invoice::PayeePubKey { inner: unsafe { (if ret.is_none() { core::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning_invoice::PayeePubKey<>) as *mut _ }, is_owned: false };
        local_ret
 }
 
@@ -1683,7 +1698,7 @@ pub extern "C" fn RawInvoice_payee_pub_key(this_arg: &RawInvoice) -> crate::ligh
 #[no_mangle]
 pub extern "C" fn RawInvoice_description_hash(this_arg: &RawInvoice) -> crate::lightning_invoice::Sha256 {
        let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.description_hash();
-       let mut local_ret = crate::lightning_invoice::Sha256 { inner: unsafe { (if ret.is_none() { std::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning_invoice::Sha256<>) as *mut _ }, is_owned: false };
+       let mut local_ret = crate::lightning_invoice::Sha256 { inner: unsafe { (if ret.is_none() { core::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning_invoice::Sha256<>) as *mut _ }, is_owned: false };
        local_ret
 }
 
@@ -1693,7 +1708,7 @@ pub extern "C" fn RawInvoice_description_hash(this_arg: &RawInvoice) -> crate::l
 #[no_mangle]
 pub extern "C" fn RawInvoice_expiry_time(this_arg: &RawInvoice) -> crate::lightning_invoice::ExpiryTime {
        let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.expiry_time();
-       let mut local_ret = crate::lightning_invoice::ExpiryTime { inner: unsafe { (if ret.is_none() { std::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning_invoice::ExpiryTime<>) as *mut _ }, is_owned: false };
+       let mut local_ret = crate::lightning_invoice::ExpiryTime { inner: unsafe { (if ret.is_none() { core::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning_invoice::ExpiryTime<>) as *mut _ }, is_owned: false };
        local_ret
 }
 
@@ -1703,7 +1718,7 @@ pub extern "C" fn RawInvoice_expiry_time(this_arg: &RawInvoice) -> crate::lightn
 #[no_mangle]
 pub extern "C" fn RawInvoice_min_final_cltv_expiry(this_arg: &RawInvoice) -> crate::lightning_invoice::MinFinalCltvExpiry {
        let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.min_final_cltv_expiry();
-       let mut local_ret = crate::lightning_invoice::MinFinalCltvExpiry { inner: unsafe { (if ret.is_none() { std::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning_invoice::MinFinalCltvExpiry<>) as *mut _ }, is_owned: false };
+       let mut local_ret = crate::lightning_invoice::MinFinalCltvExpiry { inner: unsafe { (if ret.is_none() { core::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning_invoice::MinFinalCltvExpiry<>) as *mut _ }, is_owned: false };
        local_ret
 }
 
@@ -1723,7 +1738,7 @@ pub extern "C" fn RawInvoice_payment_secret(this_arg: &RawInvoice) -> crate::c_t
 #[no_mangle]
 pub extern "C" fn RawInvoice_features(this_arg: &RawInvoice) -> crate::lightning::ln::features::InvoiceFeatures {
        let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.features();
-       let mut local_ret = crate::lightning::ln::features::InvoiceFeatures { inner: unsafe { (if ret.is_none() { std::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning::ln::features::InvoiceFeatures<>) as *mut _ }, is_owned: false };
+       let mut local_ret = crate::lightning::ln::features::InvoiceFeatures { inner: unsafe { (if ret.is_none() { core::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning::ln::features::InvoiceFeatures<>) as *mut _ }, is_owned: false };
        local_ret
 }
 
@@ -1750,9 +1765,9 @@ pub extern "C" fn RawInvoice_currency(this_arg: &RawInvoice) -> crate::lightning
        crate::lightning_invoice::Currency::native_into(ret)
 }
 
-/// Create a new `PositiveTimestamp` from a unix timestamp in the Range
-/// `0...SYSTEM_TIME_MAX_UNIX_TIMESTAMP - MAX_EXPIRY_TIME`, otherwise return a
-/// `CreationError::TimestampOutOfBounds`.
+/// Creates a `PositiveTimestamp` from a Unix timestamp in the range `0..=MAX_TIMESTAMP`.
+///
+/// Otherwise, returns a [`CreationError::TimestampOutOfBounds`].
 #[must_use]
 #[no_mangle]
 pub extern "C" fn PositiveTimestamp_from_unix_timestamp(mut unix_seconds: u64) -> crate::c_types::derived::CResult_PositiveTimestampCreationErrorZ {
@@ -1761,9 +1776,10 @@ pub extern "C" fn PositiveTimestamp_from_unix_timestamp(mut unix_seconds: u64) -
        local_ret
 }
 
-/// Create a new `PositiveTimestamp` from a `SystemTime` with a corresponding unix timestamp in
-/// the Range `0...SYSTEM_TIME_MAX_UNIX_TIMESTAMP - MAX_EXPIRY_TIME`, otherwise return a
-/// `CreationError::TimestampOutOfBounds`.
+/// Creates a `PositiveTimestamp` from a [`SystemTime`] with a corresponding Unix timestamp in
+/// the range `0..=MAX_TIMESTAMP`.
+///
+/// Otherwise, returns a [`CreationError::TimestampOutOfBounds`].
 #[must_use]
 #[no_mangle]
 pub extern "C" fn PositiveTimestamp_from_system_time(mut time: u64) -> crate::c_types::derived::CResult_PositiveTimestampCreationErrorZ {
@@ -1772,7 +1788,19 @@ pub extern "C" fn PositiveTimestamp_from_system_time(mut time: u64) -> crate::c_
        local_ret
 }
 
-/// Returns the UNIX timestamp representing the stored time
+/// Creates a `PositiveTimestamp` from a [`Duration`] since the Unix epoch in the range
+/// `0..=MAX_TIMESTAMP`.
+///
+/// Otherwise, returns a [`CreationError::TimestampOutOfBounds`].
+#[must_use]
+#[no_mangle]
+pub extern "C" fn PositiveTimestamp_from_duration_since_epoch(mut duration: u64) -> crate::c_types::derived::CResult_PositiveTimestampCreationErrorZ {
+       let mut ret = lightning_invoice::PositiveTimestamp::from_duration_since_epoch(core::time::Duration::from_secs(duration));
+       let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning_invoice::PositiveTimestamp { inner: ObjOps::heap_alloc(o), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning_invoice::CreationError::native_into(e) }).into() };
+       local_ret
+}
+
+/// Returns the Unix timestamp representing the stored time
 #[must_use]
 #[no_mangle]
 pub extern "C" fn PositiveTimestamp_as_unix_timestamp(this_arg: &PositiveTimestamp) -> u64 {
@@ -1780,7 +1808,15 @@ pub extern "C" fn PositiveTimestamp_as_unix_timestamp(this_arg: &PositiveTimesta
        ret
 }
 
-/// Returns a reference to the internal `SystemTime` time representation
+/// Returns the duration of the stored time since the Unix epoch
+#[must_use]
+#[no_mangle]
+pub extern "C" fn PositiveTimestamp_as_duration_since_epoch(this_arg: &PositiveTimestamp) -> u64 {
+       let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.as_duration_since_epoch();
+       ret.as_secs()
+}
+
+/// Returns the [`SystemTime`] representing the stored time
 #[must_use]
 #[no_mangle]
 pub extern "C" fn PositiveTimestamp_as_time(this_arg: &PositiveTimestamp) -> u64 {
@@ -1833,7 +1869,7 @@ pub extern "C" fn Invoice_from_signed(mut signed_invoice: crate::lightning_invoi
        local_ret
 }
 
-/// Returns the `Invoice`'s timestamp (should equal it's creation time)
+/// Returns the `Invoice`'s timestamp (should equal its creation time)
 #[must_use]
 #[no_mangle]
 pub extern "C" fn Invoice_timestamp(this_arg: &Invoice) -> u64 {
@@ -1841,6 +1877,14 @@ pub extern "C" fn Invoice_timestamp(this_arg: &Invoice) -> u64 {
        ret.duration_since(::std::time::SystemTime::UNIX_EPOCH).expect("Times must be post-1970").as_secs()
 }
 
+/// Returns the `Invoice`'s timestamp as a duration since the Unix epoch
+#[must_use]
+#[no_mangle]
+pub extern "C" fn Invoice_duration_since_epoch(this_arg: &Invoice) -> u64 {
+       let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.duration_since_epoch();
+       ret.as_secs()
+}
+
 /// Returns the hash to which we will receive the preimage on completion of the payment
 #[must_use]
 #[no_mangle]
@@ -1875,7 +1919,7 @@ pub extern "C" fn Invoice_payment_secret(this_arg: &Invoice) -> *const [u8; 32]
 #[no_mangle]
 pub extern "C" fn Invoice_features(this_arg: &Invoice) -> crate::lightning::ln::features::InvoiceFeatures {
        let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.features();
-       let mut local_ret = crate::lightning::ln::features::InvoiceFeatures { inner: unsafe { (if ret.is_none() { std::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning::ln::features::InvoiceFeatures<>) as *mut _ }, is_owned: false };
+       let mut local_ret = crate::lightning::ln::features::InvoiceFeatures { inner: unsafe { (if ret.is_none() { core::ptr::null() } else { ObjOps::nonnull_ptr_to_inner( { (ret.unwrap()) }) } as *const lightning::ln::features::InvoiceFeatures<>) as *mut _ }, is_owned: false };
        local_ret
 }
 
@@ -1903,6 +1947,15 @@ pub extern "C" fn Invoice_is_expired(this_arg: &Invoice) -> bool {
        ret
 }
 
+/// Returns whether the expiry time would pass at the given point in time.
+/// `at_time` is the timestamp as a duration since the Unix epoch.
+#[must_use]
+#[no_mangle]
+pub extern "C" fn Invoice_would_expire(this_arg: &Invoice, mut at_time: u64) -> bool {
+       let mut ret = unsafe { &*ObjOps::untweak_ptr(this_arg.inner) }.would_expire(core::time::Duration::from_secs(at_time));
+       ret
+}
+
 /// Returns the invoice's `min_final_cltv_expiry` time, if present, otherwise
 /// [`DEFAULT_MIN_FINAL_CLTV_EXPIRY`].
 #[must_use]
@@ -1967,26 +2020,20 @@ pub extern "C" fn Description_into_inner(mut this_arg: Description) -> crate::c_
        ret.into()
 }
 
-/// Construct an `ExpiryTime` from seconds. If there exists a `PositiveTimestamp` which would
-/// overflow on adding the `EpiryTime` to it then this function will return a
-/// `CreationError::ExpiryTimeOutOfBounds`.
+/// Construct an `ExpiryTime` from seconds.
 #[must_use]
 #[no_mangle]
-pub extern "C" fn ExpiryTime_from_seconds(mut seconds: u64) -> crate::c_types::derived::CResult_ExpiryTimeCreationErrorZ {
+pub extern "C" fn ExpiryTime_from_seconds(mut seconds: u64) -> crate::lightning_invoice::ExpiryTime {
        let mut ret = lightning_invoice::ExpiryTime::from_seconds(seconds);
-       let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning_invoice::ExpiryTime { inner: ObjOps::heap_alloc(o), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning_invoice::CreationError::native_into(e) }).into() };
-       local_ret
+       crate::lightning_invoice::ExpiryTime { inner: ObjOps::heap_alloc(ret), is_owned: true }
 }
 
-/// Construct an `ExpiryTime` from a `Duration`. If there exists a `PositiveTimestamp` which
-/// would overflow on adding the `EpiryTime` to it then this function will return a
-/// `CreationError::ExpiryTimeOutOfBounds`.
+/// Construct an `ExpiryTime` from a `Duration`.
 #[must_use]
 #[no_mangle]
-pub extern "C" fn ExpiryTime_from_duration(mut duration: u64) -> crate::c_types::derived::CResult_ExpiryTimeCreationErrorZ {
-       let mut ret = lightning_invoice::ExpiryTime::from_duration(std::time::Duration::from_secs(duration));
-       let mut local_ret = match ret { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::lightning_invoice::ExpiryTime { inner: ObjOps::heap_alloc(o), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::lightning_invoice::CreationError::native_into(e) }).into() };
-       local_ret
+pub extern "C" fn ExpiryTime_from_duration(mut duration: u64) -> crate::lightning_invoice::ExpiryTime {
+       let mut ret = lightning_invoice::ExpiryTime::from_duration(core::time::Duration::from_secs(duration));
+       crate::lightning_invoice::ExpiryTime { inner: ObjOps::heap_alloc(ret), is_owned: true }
 }
 
 /// Returns the expiry time in seconds
@@ -2031,10 +2078,15 @@ pub enum CreationError {
        DescriptionTooLong,
        /// The specified route has too many hops and can't be encoded
        RouteTooLong,
-       /// The unix timestamp of the supplied date is <0 or can't be represented as `SystemTime`
+       /// The Unix timestamp of the supplied date is less than zero or greater than 35-bits
        TimestampOutOfBounds,
-       /// The supplied expiry time could cause an overflow if added to a `PositiveTimestamp`
-       ExpiryTimeOutOfBounds,
+       /// The supplied millisatoshi amount was greater than the total bitcoin supply.
+       InvalidAmount,
+       /// Route hints were required for this invoice and were missing. Applies to
+       /// [phantom invoices].
+       ///
+       /// [phantom invoices]: crate::utils::create_phantom_invoice
+       MissingRouteHints,
 }
 use lightning_invoice::CreationError as nativeCreationError;
 impl CreationError {
@@ -2044,7 +2096,8 @@ impl CreationError {
                        CreationError::DescriptionTooLong => nativeCreationError::DescriptionTooLong,
                        CreationError::RouteTooLong => nativeCreationError::RouteTooLong,
                        CreationError::TimestampOutOfBounds => nativeCreationError::TimestampOutOfBounds,
-                       CreationError::ExpiryTimeOutOfBounds => nativeCreationError::ExpiryTimeOutOfBounds,
+                       CreationError::InvalidAmount => nativeCreationError::InvalidAmount,
+                       CreationError::MissingRouteHints => nativeCreationError::MissingRouteHints,
                }
        }
        #[allow(unused)]
@@ -2053,7 +2106,8 @@ impl CreationError {
                        CreationError::DescriptionTooLong => nativeCreationError::DescriptionTooLong,
                        CreationError::RouteTooLong => nativeCreationError::RouteTooLong,
                        CreationError::TimestampOutOfBounds => nativeCreationError::TimestampOutOfBounds,
-                       CreationError::ExpiryTimeOutOfBounds => nativeCreationError::ExpiryTimeOutOfBounds,
+                       CreationError::InvalidAmount => nativeCreationError::InvalidAmount,
+                       CreationError::MissingRouteHints => nativeCreationError::MissingRouteHints,
                }
        }
        #[allow(unused)]
@@ -2062,7 +2116,8 @@ impl CreationError {
                        nativeCreationError::DescriptionTooLong => CreationError::DescriptionTooLong,
                        nativeCreationError::RouteTooLong => CreationError::RouteTooLong,
                        nativeCreationError::TimestampOutOfBounds => CreationError::TimestampOutOfBounds,
-                       nativeCreationError::ExpiryTimeOutOfBounds => CreationError::ExpiryTimeOutOfBounds,
+                       nativeCreationError::InvalidAmount => CreationError::InvalidAmount,
+                       nativeCreationError::MissingRouteHints => CreationError::MissingRouteHints,
                }
        }
        #[allow(unused)]
@@ -2071,7 +2126,8 @@ impl CreationError {
                        nativeCreationError::DescriptionTooLong => CreationError::DescriptionTooLong,
                        nativeCreationError::RouteTooLong => CreationError::RouteTooLong,
                        nativeCreationError::TimestampOutOfBounds => CreationError::TimestampOutOfBounds,
-                       nativeCreationError::ExpiryTimeOutOfBounds => CreationError::ExpiryTimeOutOfBounds,
+                       nativeCreationError::InvalidAmount => CreationError::InvalidAmount,
+                       nativeCreationError::MissingRouteHints => CreationError::MissingRouteHints,
                }
        }
 }
@@ -2093,9 +2149,13 @@ pub extern "C" fn CreationError_route_too_long() -> CreationError {
 pub extern "C" fn CreationError_timestamp_out_of_bounds() -> CreationError {
        CreationError::TimestampOutOfBounds}
 #[no_mangle]
-/// Utility method to constructs a new ExpiryTimeOutOfBounds-variant CreationError
-pub extern "C" fn CreationError_expiry_time_out_of_bounds() -> CreationError {
-       CreationError::ExpiryTimeOutOfBounds}
+/// Utility method to constructs a new InvalidAmount-variant CreationError
+pub extern "C" fn CreationError_invalid_amount() -> CreationError {
+       CreationError::InvalidAmount}
+#[no_mangle]
+/// Utility method to constructs a new MissingRouteHints-variant CreationError
+pub extern "C" fn CreationError_missing_route_hints() -> CreationError {
+       CreationError::MissingRouteHints}
 /// Checks if two CreationErrors contain equal inner contents.
 /// This ignores pointers and is_owned flags and looks at the values in fields.
 #[no_mangle]
@@ -2105,7 +2165,7 @@ pub extern "C" fn CreationError_eq(a: &CreationError, b: &CreationError) -> bool
 #[no_mangle]
 /// Get the string representation of a CreationError object
 pub extern "C" fn CreationError_to_str(o: &crate::lightning_invoice::CreationError) -> Str {
-       format!("{}", &o.to_native()).into()
+       alloc::format!("{}", &o.to_native()).into()
 }
 /// Errors that may occur when converting a `RawInvoice` to an `Invoice`. They relate to the
 /// requirements sections in BOLT #11
@@ -2252,7 +2312,7 @@ pub extern "C" fn SemanticError_eq(a: &SemanticError, b: &SemanticError) -> bool
 #[no_mangle]
 /// Get the string representation of a SemanticError object
 pub extern "C" fn SemanticError_to_str(o: &crate::lightning_invoice::SemanticError) -> Str {
-       format!("{}", &o.to_native()).into()
+       alloc::format!("{}", &o.to_native()).into()
 }
 /// When signing using a fallible method either an user-supplied `SignError` or a `CreationError`
 /// may occur.
@@ -2351,5 +2411,5 @@ pub extern "C" fn SignOrCreationError_eq(a: &SignOrCreationError, b: &SignOrCrea
 #[no_mangle]
 /// Get the string representation of a SignOrCreationError object
 pub extern "C" fn SignOrCreationError_to_str(o: &crate::lightning_invoice::SignOrCreationError) -> Str {
-       format!("{}", &o.to_native()).into()
+       alloc::format!("{}", &o.to_native()).into()
 }