Add description hash to receive payment (#440)

* Add option to hash description

* Fix Flutter gen

* Switch to upstream boltz-rust

* Address feedback
This commit is contained in:
Ross Savage
2024-08-29 08:17:10 +02:00
committed by GitHub
parent 34774647bf
commit deb9ed1b09
20 changed files with 344 additions and 119 deletions

2
cli/Cargo.lock generated
View File

@@ -500,7 +500,7 @@ dependencies = [
[[package]]
name = "boltz-client"
version = "0.1.3"
source = "git+https://github.com/dangeross/boltz-rust?branch=savage-breez-20240807#7e3ebb1fc43b8b9bda041d76a07fb85bd7251085"
source = "git+https://github.com/SatoshiPortal/boltz-rust?rev=c140193dab075093e1cfdcc1dd608be8e828d1ef#c140193dab075093e1cfdcc1dd608be8e828d1ef"
dependencies = [
"bip39",
"bitcoin 0.31.2",

View File

@@ -68,6 +68,10 @@ pub(crate) enum Command {
/// Optional description for the invoice
#[clap(short = 'd', long = "description")]
description: Option<String>,
/// Optional if true uses the hash of the description
#[clap(name = "use_description_hash", short = 's', long = "desc_hash")]
use_description_hash: Option<bool>,
},
/// Generates an URL to buy bitcoin from a 3rd party provider
BuyBitcoin {
@@ -218,6 +222,7 @@ pub(crate) async fn handle_command(
payment_method,
payer_amount_sat,
description,
use_description_hash,
} => {
let prepare_response = sdk
.prepare_receive_payment(&PrepareReceiveRequest {
@@ -238,6 +243,7 @@ pub(crate) async fn handle_command(
.receive_payment(&ReceivePaymentRequest {
prepare_response,
description,
use_description_hash,
})
.await?;

2
lib/Cargo.lock generated
View File

@@ -620,7 +620,7 @@ dependencies = [
[[package]]
name = "boltz-client"
version = "0.1.3"
source = "git+https://github.com/dangeross/boltz-rust?branch=savage-breez-20240807#7e3ebb1fc43b8b9bda041d76a07fb85bd7251085"
source = "git+https://github.com/SatoshiPortal/boltz-rust?rev=c140193dab075093e1cfdcc1dd608be8e828d1ef#c140193dab075093e1cfdcc1dd608be8e828d1ef"
dependencies = [
"bip39",
"bitcoin 0.31.2",

View File

@@ -155,8 +155,9 @@ typedef struct wire_cst_prepare_receive_response {
} wire_cst_prepare_receive_response;
typedef struct wire_cst_receive_payment_request {
struct wire_cst_list_prim_u_8_strict *description;
struct wire_cst_prepare_receive_response prepare_response;
struct wire_cst_list_prim_u_8_strict *description;
bool *use_description_hash;
} wire_cst_receive_payment_request;
typedef struct wire_cst_refund_request {
@@ -777,6 +778,10 @@ typedef struct wire_cst_PaymentError_Generic {
struct wire_cst_list_prim_u_8_strict *err;
} wire_cst_PaymentError_Generic;
typedef struct wire_cst_PaymentError_InvalidDescription {
struct wire_cst_list_prim_u_8_strict *err;
} wire_cst_PaymentError_InvalidDescription;
typedef struct wire_cst_PaymentError_InvalidInvoice {
struct wire_cst_list_prim_u_8_strict *err;
} wire_cst_PaymentError_InvalidInvoice;
@@ -806,6 +811,7 @@ typedef union PaymentErrorKind {
struct wire_cst_PaymentError_AmountMissing AmountMissing;
struct wire_cst_PaymentError_InvalidNetwork InvalidNetwork;
struct wire_cst_PaymentError_Generic Generic;
struct wire_cst_PaymentError_InvalidDescription InvalidDescription;
struct wire_cst_PaymentError_InvalidInvoice InvalidInvoice;
struct wire_cst_PaymentError_LwkError LwkError;
struct wire_cst_PaymentError_ReceiveError ReceiveError;

View File

@@ -282,6 +282,7 @@ enum PaymentError {
"Generic",
"InvalidOrExpiredFees",
"InsufficientFunds",
"InvalidDescription",
"InvalidInvoice",
"InvalidNetwork",
"InvalidPreimage",
@@ -368,6 +369,7 @@ dictionary PrepareReceiveResponse {
dictionary ReceivePaymentRequest {
PrepareReceiveResponse prepare_response;
string? description = null;
boolean? use_description_hash = null;
};
dictionary ReceivePaymentResponse {

View File

@@ -14,7 +14,7 @@ frb = ["dep:flutter_rust_bridge"]
[dependencies]
anyhow = { workspace = true }
bip39 = "2.0.0"
boltz-client = { git = "https://github.com/dangeross/boltz-rust", branch = "savage-breez-20240807" }
boltz-client = { git = "https://github.com/SatoshiPortal/boltz-rust", rev = "c140193dab075093e1cfdcc1dd608be8e828d1ef" }
chrono = "0.4"
env_logger = "0.11"
flutter_rust_bridge = { version = "=2.2.0", features = [

View File

@@ -85,6 +85,9 @@ pub enum PaymentError {
#[error("Cannot pay: not enough funds")]
InsufficientFunds,
#[error("Invalid description: {err}")]
InvalidDescription { err: String },
#[error("The specified invoice is not valid: {err}")]
InvalidInvoice { err: String },

View File

@@ -3927,6 +3927,7 @@ pub union PaymentErrorKind {
AmountMissing: wire_cst_PaymentError_AmountMissing,
NetworkMismatch: wire_cst_PaymentError_NetworkMismatch,
Generic: wire_cst_PaymentError_Generic,
InvalidDescription: wire_cst_PaymentError_InvalidDescription,
InvalidInvoice: wire_cst_PaymentError_InvalidInvoice,
LwkError: wire_cst_PaymentError_LwkError,
ReceiveError: wire_cst_PaymentError_ReceiveError,
@@ -3952,6 +3953,11 @@ pub struct wire_cst_PaymentError_Generic {
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_PaymentError_InvalidDescription {
err: *mut wire_cst_list_prim_u_8_strict,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_PaymentError_InvalidInvoice {
err: *mut wire_cst_list_prim_u_8_strict,
}

View File

@@ -3097,29 +3097,33 @@ impl SseDecode for crate::error::PaymentError {
}
9 => {
let mut var_err = <String>::sse_decode(deserializer);
return crate::error::PaymentError::InvalidInvoice { err: var_err };
return crate::error::PaymentError::InvalidDescription { err: var_err };
}
10 => {
return crate::error::PaymentError::InvalidPreimage;
let mut var_err = <String>::sse_decode(deserializer);
return crate::error::PaymentError::InvalidInvoice { err: var_err };
}
11 => {
return crate::error::PaymentError::InvalidPreimage;
}
12 => {
let mut var_err = <String>::sse_decode(deserializer);
return crate::error::PaymentError::LwkError { err: var_err };
}
12 => {
13 => {
return crate::error::PaymentError::PairsNotFound;
}
13 => {
14 => {
return crate::error::PaymentError::PaymentTimeout;
}
14 => {
15 => {
return crate::error::PaymentError::PersistError;
}
15 => {
16 => {
let mut var_err = <String>::sse_decode(deserializer);
return crate::error::PaymentError::ReceiveError { err: var_err };
}
16 => {
17 => {
let mut var_err = <String>::sse_decode(deserializer);
let mut var_refundTxId = <String>::sse_decode(deserializer);
return crate::error::PaymentError::Refunded {
@@ -3127,14 +3131,14 @@ impl SseDecode for crate::error::PaymentError {
refund_tx_id: var_refundTxId,
};
}
17 => {
18 => {
return crate::error::PaymentError::SelfTransferNotSupported;
}
18 => {
19 => {
let mut var_err = <String>::sse_decode(deserializer);
return crate::error::PaymentError::SendError { err: var_err };
}
19 => {
20 => {
let mut var_err = <String>::sse_decode(deserializer);
return crate::error::PaymentError::SignerError { err: var_err };
}
@@ -3332,12 +3336,14 @@ impl SseDecode for crate::bindings::Rate {
impl SseDecode for crate::model::ReceivePaymentRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_description = <Option<String>>::sse_decode(deserializer);
let mut var_prepareResponse =
<crate::model::PrepareReceiveResponse>::sse_decode(deserializer);
let mut var_description = <Option<String>>::sse_decode(deserializer);
let mut var_useDescriptionHash = <Option<bool>>::sse_decode(deserializer);
return crate::model::ReceivePaymentRequest {
description: var_description,
prepare_response: var_prepareResponse,
description: var_description,
use_description_hash: var_useDescriptionHash,
};
}
}
@@ -4794,31 +4800,34 @@ impl flutter_rust_bridge::IntoDart for crate::error::PaymentError {
}
crate::error::PaymentError::InvalidOrExpiredFees => [7.into_dart()].into_dart(),
crate::error::PaymentError::InsufficientFunds => [8.into_dart()].into_dart(),
crate::error::PaymentError::InvalidInvoice { err } => {
crate::error::PaymentError::InvalidDescription { err } => {
[9.into_dart(), err.into_into_dart().into_dart()].into_dart()
}
crate::error::PaymentError::InvalidPreimage => [10.into_dart()].into_dart(),
crate::error::PaymentError::LwkError { err } => {
[11.into_dart(), err.into_into_dart().into_dart()].into_dart()
crate::error::PaymentError::InvalidInvoice { err } => {
[10.into_dart(), err.into_into_dart().into_dart()].into_dart()
}
crate::error::PaymentError::PairsNotFound => [12.into_dart()].into_dart(),
crate::error::PaymentError::PaymentTimeout => [13.into_dart()].into_dart(),
crate::error::PaymentError::PersistError => [14.into_dart()].into_dart(),
crate::error::PaymentError::InvalidPreimage => [11.into_dart()].into_dart(),
crate::error::PaymentError::LwkError { err } => {
[12.into_dart(), err.into_into_dart().into_dart()].into_dart()
}
crate::error::PaymentError::PairsNotFound => [13.into_dart()].into_dart(),
crate::error::PaymentError::PaymentTimeout => [14.into_dart()].into_dart(),
crate::error::PaymentError::PersistError => [15.into_dart()].into_dart(),
crate::error::PaymentError::ReceiveError { err } => {
[15.into_dart(), err.into_into_dart().into_dart()].into_dart()
[16.into_dart(), err.into_into_dart().into_dart()].into_dart()
}
crate::error::PaymentError::Refunded { err, refund_tx_id } => [
16.into_dart(),
17.into_dart(),
err.into_into_dart().into_dart(),
refund_tx_id.into_into_dart().into_dart(),
]
.into_dart(),
crate::error::PaymentError::SelfTransferNotSupported => [17.into_dart()].into_dart(),
crate::error::PaymentError::SelfTransferNotSupported => [18.into_dart()].into_dart(),
crate::error::PaymentError::SendError { err } => {
[18.into_dart(), err.into_into_dart().into_dart()].into_dart()
[19.into_dart(), err.into_into_dart().into_dart()].into_dart()
}
crate::error::PaymentError::SignerError { err } => {
[19.into_dart(), err.into_into_dart().into_dart()].into_dart()
[20.into_dart(), err.into_into_dart().into_dart()].into_dart()
}
_ => {
unimplemented!("");
@@ -5128,8 +5137,9 @@ impl flutter_rust_bridge::IntoIntoDart<FrbWrapper<crate::bindings::Rate>>
impl flutter_rust_bridge::IntoDart for crate::model::ReceivePaymentRequest {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.description.into_into_dart().into_dart(),
self.prepare_response.into_into_dart().into_dart(),
self.description.into_into_dart().into_dart(),
self.use_description_hash.into_into_dart().into_dart(),
]
.into_dart()
}
@@ -6439,44 +6449,48 @@ impl SseEncode for crate::error::PaymentError {
crate::error::PaymentError::InsufficientFunds => {
<i32>::sse_encode(8, serializer);
}
crate::error::PaymentError::InvalidInvoice { err } => {
crate::error::PaymentError::InvalidDescription { err } => {
<i32>::sse_encode(9, serializer);
<String>::sse_encode(err, serializer);
}
crate::error::PaymentError::InvalidPreimage => {
crate::error::PaymentError::InvalidInvoice { err } => {
<i32>::sse_encode(10, serializer);
<String>::sse_encode(err, serializer);
}
crate::error::PaymentError::InvalidPreimage => {
<i32>::sse_encode(11, serializer);
}
crate::error::PaymentError::LwkError { err } => {
<i32>::sse_encode(11, serializer);
<i32>::sse_encode(12, serializer);
<String>::sse_encode(err, serializer);
}
crate::error::PaymentError::PairsNotFound => {
<i32>::sse_encode(12, serializer);
}
crate::error::PaymentError::PaymentTimeout => {
<i32>::sse_encode(13, serializer);
}
crate::error::PaymentError::PersistError => {
crate::error::PaymentError::PaymentTimeout => {
<i32>::sse_encode(14, serializer);
}
crate::error::PaymentError::ReceiveError { err } => {
crate::error::PaymentError::PersistError => {
<i32>::sse_encode(15, serializer);
}
crate::error::PaymentError::ReceiveError { err } => {
<i32>::sse_encode(16, serializer);
<String>::sse_encode(err, serializer);
}
crate::error::PaymentError::Refunded { err, refund_tx_id } => {
<i32>::sse_encode(16, serializer);
<i32>::sse_encode(17, serializer);
<String>::sse_encode(err, serializer);
<String>::sse_encode(refund_tx_id, serializer);
}
crate::error::PaymentError::SelfTransferNotSupported => {
<i32>::sse_encode(17, serializer);
<i32>::sse_encode(18, serializer);
}
crate::error::PaymentError::SendError { err } => {
<i32>::sse_encode(18, serializer);
<i32>::sse_encode(19, serializer);
<String>::sse_encode(err, serializer);
}
crate::error::PaymentError::SignerError { err } => {
<i32>::sse_encode(19, serializer);
<i32>::sse_encode(20, serializer);
<String>::sse_encode(err, serializer);
}
_ => {
@@ -6636,8 +6650,9 @@ impl SseEncode for crate::bindings::Rate {
impl SseEncode for crate::model::ReceivePaymentRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<Option<String>>::sse_encode(self.description, serializer);
<crate::model::PrepareReceiveResponse>::sse_encode(self.prepare_response, serializer);
<Option<String>>::sse_encode(self.description, serializer);
<Option<bool>>::sse_encode(self.use_description_hash, serializer);
}
}
@@ -8075,42 +8090,48 @@ mod io {
7 => crate::error::PaymentError::InvalidOrExpiredFees,
8 => crate::error::PaymentError::InsufficientFunds,
9 => {
let ans = unsafe { self.kind.InvalidDescription };
crate::error::PaymentError::InvalidDescription {
err: ans.err.cst_decode(),
}
}
10 => {
let ans = unsafe { self.kind.InvalidInvoice };
crate::error::PaymentError::InvalidInvoice {
err: ans.err.cst_decode(),
}
}
10 => crate::error::PaymentError::InvalidPreimage,
11 => {
11 => crate::error::PaymentError::InvalidPreimage,
12 => {
let ans = unsafe { self.kind.LwkError };
crate::error::PaymentError::LwkError {
err: ans.err.cst_decode(),
}
}
12 => crate::error::PaymentError::PairsNotFound,
13 => crate::error::PaymentError::PaymentTimeout,
14 => crate::error::PaymentError::PersistError,
15 => {
13 => crate::error::PaymentError::PairsNotFound,
14 => crate::error::PaymentError::PaymentTimeout,
15 => crate::error::PaymentError::PersistError,
16 => {
let ans = unsafe { self.kind.ReceiveError };
crate::error::PaymentError::ReceiveError {
err: ans.err.cst_decode(),
}
}
16 => {
17 => {
let ans = unsafe { self.kind.Refunded };
crate::error::PaymentError::Refunded {
err: ans.err.cst_decode(),
refund_tx_id: ans.refund_tx_id.cst_decode(),
}
}
17 => crate::error::PaymentError::SelfTransferNotSupported,
18 => {
18 => crate::error::PaymentError::SelfTransferNotSupported,
19 => {
let ans = unsafe { self.kind.SendError };
crate::error::PaymentError::SendError {
err: ans.err.cst_decode(),
}
}
19 => {
20 => {
let ans = unsafe { self.kind.SignerError };
crate::error::PaymentError::SignerError {
err: ans.err.cst_decode(),
@@ -8228,8 +8249,9 @@ mod io {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::ReceivePaymentRequest {
crate::model::ReceivePaymentRequest {
description: self.description.cst_decode(),
prepare_response: self.prepare_response.cst_decode(),
description: self.description.cst_decode(),
use_description_hash: self.use_description_hash.cst_decode(),
}
}
}
@@ -9197,8 +9219,9 @@ mod io {
impl NewWithNullPtr for wire_cst_receive_payment_request {
fn new_with_null_ptr() -> Self {
Self {
description: core::ptr::null_mut(),
prepare_response: Default::default(),
description: core::ptr::null_mut(),
use_description_hash: core::ptr::null_mut(),
}
}
}
@@ -10839,6 +10862,7 @@ mod io {
AmountMissing: wire_cst_PaymentError_AmountMissing,
InvalidNetwork: wire_cst_PaymentError_InvalidNetwork,
Generic: wire_cst_PaymentError_Generic,
InvalidDescription: wire_cst_PaymentError_InvalidDescription,
InvalidInvoice: wire_cst_PaymentError_InvalidInvoice,
LwkError: wire_cst_PaymentError_LwkError,
ReceiveError: wire_cst_PaymentError_ReceiveError,
@@ -10864,6 +10888,11 @@ mod io {
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_PaymentError_InvalidDescription {
err: *mut wire_cst_list_prim_u_8_strict,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_PaymentError_InvalidInvoice {
err: *mut wire_cst_list_prim_u_8_strict,
}
@@ -10967,8 +10996,9 @@ mod io {
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_receive_payment_request {
description: *mut wire_cst_list_prim_u_8_strict,
prepare_response: wire_cst_prepare_receive_response,
description: *mut wire_cst_list_prim_u_8_strict,
use_description_hash: *mut bool,
}
#[repr(C)]
#[derive(Clone, Copy)]

View File

@@ -224,8 +224,11 @@ pub struct PrepareReceiveResponse {
/// An argument when calling [crate::sdk::LiquidSdk::receive_payment].
#[derive(Debug, Serialize)]
pub struct ReceivePaymentRequest {
pub description: Option<String>,
pub prepare_response: PrepareReceiveResponse,
/// The description for this payment request.
pub description: Option<String>,
/// If set to true, then the hash of the description will be used.
pub use_description_hash: Option<bool>,
}
/// Returned when calling [crate::sdk::LiquidSdk::receive_payment].

View File

@@ -1400,8 +1400,9 @@ impl LiquidSdk {
/// # Arguments
///
/// * `req` - the [ReceivePaymentRequest] containing:
/// * `description` - the optional payment description
/// * `prepare_response` - the [PrepareReceiveResponse] from calling [LiquidSdk::prepare_receive_payment]
/// * `description` - the optional payment description
/// * `use_description_hash` - optional if true uses the hash of the description
///
/// # Returns
///
@@ -1424,7 +1425,22 @@ impl LiquidSdk {
let Some(amount_sat) = amount_sat else {
return Err(PaymentError::AmountMissing { err: "`amount_sat` must be specified when `PaymentMethod::Lightning` is used.".to_string() });
};
self.create_receive_swap(*amount_sat, *fees_sat, req.description.clone())
let (description, description_hash) = match (
req.description.clone(),
req.use_description_hash.unwrap_or_default(),
) {
(Some(description), true) => (
None,
Some(sha256::Hash::hash(description.as_bytes()).to_hex()),
),
(_, false) => (req.description.clone(), None),
_ => {
return Err(PaymentError::InvalidDescription {
err: "Missing payment description to hash".to_string(),
})
}
};
self.create_receive_swap(*amount_sat, *fees_sat, description, description_hash)
.await
}
PaymentMethod::BitcoinAddress => {
@@ -1464,6 +1480,7 @@ impl LiquidSdk {
payer_amount_sat: u64,
fees_sat: u64,
description: Option<String>,
description_hash: Option<String>,
) -> Result<ReceivePaymentResponse, PaymentError> {
let reverse_pair = self
.swapper
@@ -1507,6 +1524,7 @@ impl LiquidSdk {
preimage_hash: preimage.sha256,
claim_public_key: keypair.public_key().into(),
description,
description_hash,
address: Some(mrh_addr_str.clone()),
address_signature: Some(mrh_addr_hash_sig.to_hex()),
referral_id: None,
@@ -1551,7 +1569,7 @@ impl LiquidSdk {
&swap_id,
&invoice.to_string(),
)?;
let description = match invoice.description() {
let invoice_description = match invoice.description() {
Bolt11InvoiceDescription::Direct(msg) => Some(msg.to_string()),
Bolt11InvoiceDescription::Hash(_) => None,
};
@@ -1562,7 +1580,7 @@ impl LiquidSdk {
create_response_json,
claim_private_key: keypair.display_secret().to_string(),
invoice: invoice.to_string(),
description,
description: invoice_description,
payer_amount_sat,
receiver_amount_sat,
claim_fees_sat: reverse_pair.fees.claim_estimate(),
@@ -2094,6 +2112,7 @@ impl LiquidSdk {
.receive_payment(&ReceivePaymentRequest {
prepare_response,
description: None,
use_description_hash: Some(false),
})
.await?;

View File

@@ -27,6 +27,9 @@ sealed class PaymentError with _$PaymentError implements FrbException {
}) = PaymentError_Generic;
const factory PaymentError.invalidOrExpiredFees() = PaymentError_InvalidOrExpiredFees;
const factory PaymentError.insufficientFunds() = PaymentError_InsufficientFunds;
const factory PaymentError.invalidDescription({
required String err,
}) = PaymentError_InvalidDescription;
const factory PaymentError.invalidInvoice({
required String err,
}) = PaymentError_InvalidInvoice;

View File

@@ -537,6 +537,87 @@ abstract class PaymentError_InsufficientFunds extends PaymentError {
const PaymentError_InsufficientFunds._() : super._();
}
/// @nodoc
abstract class _$$PaymentError_InvalidDescriptionImplCopyWith<$Res> {
factory _$$PaymentError_InvalidDescriptionImplCopyWith(_$PaymentError_InvalidDescriptionImpl value,
$Res Function(_$PaymentError_InvalidDescriptionImpl) then) =
__$$PaymentError_InvalidDescriptionImplCopyWithImpl<$Res>;
@useResult
$Res call({String err});
}
/// @nodoc
class __$$PaymentError_InvalidDescriptionImplCopyWithImpl<$Res>
extends _$PaymentErrorCopyWithImpl<$Res, _$PaymentError_InvalidDescriptionImpl>
implements _$$PaymentError_InvalidDescriptionImplCopyWith<$Res> {
__$$PaymentError_InvalidDescriptionImplCopyWithImpl(_$PaymentError_InvalidDescriptionImpl _value,
$Res Function(_$PaymentError_InvalidDescriptionImpl) _then)
: super(_value, _then);
/// Create a copy of PaymentError
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? err = null,
}) {
return _then(_$PaymentError_InvalidDescriptionImpl(
err: null == err
? _value.err
: err // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
/// @nodoc
class _$PaymentError_InvalidDescriptionImpl extends PaymentError_InvalidDescription {
const _$PaymentError_InvalidDescriptionImpl({required this.err}) : super._();
@override
final String err;
@override
String toString() {
return 'PaymentError.invalidDescription(err: $err)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$PaymentError_InvalidDescriptionImpl &&
(identical(other.err, err) || other.err == err));
}
@override
int get hashCode => Object.hash(runtimeType, err);
/// Create a copy of PaymentError
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$PaymentError_InvalidDescriptionImplCopyWith<_$PaymentError_InvalidDescriptionImpl> get copyWith =>
__$$PaymentError_InvalidDescriptionImplCopyWithImpl<_$PaymentError_InvalidDescriptionImpl>(
this, _$identity);
}
abstract class PaymentError_InvalidDescription extends PaymentError {
const factory PaymentError_InvalidDescription({required final String err}) =
_$PaymentError_InvalidDescriptionImpl;
const PaymentError_InvalidDescription._() : super._();
String get err;
/// Create a copy of PaymentError
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$PaymentError_InvalidDescriptionImplCopyWith<_$PaymentError_InvalidDescriptionImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$PaymentError_InvalidInvoiceImplCopyWith<$Res> {
factory _$$PaymentError_InvalidInvoiceImplCopyWith(

View File

@@ -2196,37 +2196,41 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
case 8:
return PaymentError_InsufficientFunds();
case 9:
return PaymentError_InvalidInvoice(
return PaymentError_InvalidDescription(
err: dco_decode_String(raw[1]),
);
case 10:
return PaymentError_InvalidPreimage();
return PaymentError_InvalidInvoice(
err: dco_decode_String(raw[1]),
);
case 11:
return PaymentError_InvalidPreimage();
case 12:
return PaymentError_LwkError(
err: dco_decode_String(raw[1]),
);
case 12:
return PaymentError_PairsNotFound();
case 13:
return PaymentError_PaymentTimeout();
return PaymentError_PairsNotFound();
case 14:
return PaymentError_PersistError();
return PaymentError_PaymentTimeout();
case 15:
return PaymentError_PersistError();
case 16:
return PaymentError_ReceiveError(
err: dco_decode_String(raw[1]),
);
case 16:
case 17:
return PaymentError_Refunded(
err: dco_decode_String(raw[1]),
refundTxId: dco_decode_String(raw[2]),
);
case 17:
return PaymentError_SelfTransferNotSupported();
case 18:
return PaymentError_SelfTransferNotSupported();
case 19:
return PaymentError_SendError(
err: dco_decode_String(raw[1]),
);
case 19:
case 20:
return PaymentError_SignerError(
err: dco_decode_String(raw[1]),
);
@@ -2383,10 +2387,11 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
ReceivePaymentRequest dco_decode_receive_payment_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}');
if (arr.length != 3) throw Exception('unexpected arr length: expect 3 but see ${arr.length}');
return ReceivePaymentRequest(
description: dco_decode_opt_String(arr[0]),
prepareResponse: dco_decode_prepare_receive_response(arr[1]),
prepareResponse: dco_decode_prepare_receive_response(arr[0]),
description: dco_decode_opt_String(arr[1]),
useDescriptionHash: dco_decode_opt_box_autoadd_bool(arr[2]),
);
}
@@ -3860,31 +3865,34 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return PaymentError_InsufficientFunds();
case 9:
var var_err = sse_decode_String(deserializer);
return PaymentError_InvalidInvoice(err: var_err);
return PaymentError_InvalidDescription(err: var_err);
case 10:
return PaymentError_InvalidPreimage();
var var_err = sse_decode_String(deserializer);
return PaymentError_InvalidInvoice(err: var_err);
case 11:
return PaymentError_InvalidPreimage();
case 12:
var var_err = sse_decode_String(deserializer);
return PaymentError_LwkError(err: var_err);
case 12:
return PaymentError_PairsNotFound();
case 13:
return PaymentError_PaymentTimeout();
return PaymentError_PairsNotFound();
case 14:
return PaymentError_PersistError();
return PaymentError_PaymentTimeout();
case 15:
return PaymentError_PersistError();
case 16:
var var_err = sse_decode_String(deserializer);
return PaymentError_ReceiveError(err: var_err);
case 16:
case 17:
var var_err = sse_decode_String(deserializer);
var var_refundTxId = sse_decode_String(deserializer);
return PaymentError_Refunded(err: var_err, refundTxId: var_refundTxId);
case 17:
return PaymentError_SelfTransferNotSupported();
case 18:
return PaymentError_SelfTransferNotSupported();
case 19:
var var_err = sse_decode_String(deserializer);
return PaymentError_SendError(err: var_err);
case 19:
case 20:
var var_err = sse_decode_String(deserializer);
return PaymentError_SignerError(err: var_err);
default:
@@ -4014,9 +4022,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
@protected
ReceivePaymentRequest sse_decode_receive_payment_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_description = sse_decode_opt_String(deserializer);
var var_prepareResponse = sse_decode_prepare_receive_response(deserializer);
return ReceivePaymentRequest(description: var_description, prepareResponse: var_prepareResponse);
var var_description = sse_decode_opt_String(deserializer);
var var_useDescriptionHash = sse_decode_opt_box_autoadd_bool(deserializer);
return ReceivePaymentRequest(
prepareResponse: var_prepareResponse,
description: var_description,
useDescriptionHash: var_useDescriptionHash);
}
@protected
@@ -5414,34 +5426,37 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_i_32(7, serializer);
case PaymentError_InsufficientFunds():
sse_encode_i_32(8, serializer);
case PaymentError_InvalidInvoice(err: final err):
case PaymentError_InvalidDescription(err: final err):
sse_encode_i_32(9, serializer);
sse_encode_String(err, serializer);
case PaymentError_InvalidPreimage():
case PaymentError_InvalidInvoice(err: final err):
sse_encode_i_32(10, serializer);
case PaymentError_LwkError(err: final err):
sse_encode_String(err, serializer);
case PaymentError_InvalidPreimage():
sse_encode_i_32(11, serializer);
case PaymentError_LwkError(err: final err):
sse_encode_i_32(12, serializer);
sse_encode_String(err, serializer);
case PaymentError_PairsNotFound():
sse_encode_i_32(12, serializer);
case PaymentError_PaymentTimeout():
sse_encode_i_32(13, serializer);
case PaymentError_PersistError():
case PaymentError_PaymentTimeout():
sse_encode_i_32(14, serializer);
case PaymentError_ReceiveError(err: final err):
case PaymentError_PersistError():
sse_encode_i_32(15, serializer);
case PaymentError_ReceiveError(err: final err):
sse_encode_i_32(16, serializer);
sse_encode_String(err, serializer);
case PaymentError_Refunded(err: final err, refundTxId: final refundTxId):
sse_encode_i_32(16, serializer);
sse_encode_i_32(17, serializer);
sse_encode_String(err, serializer);
sse_encode_String(refundTxId, serializer);
case PaymentError_SelfTransferNotSupported():
sse_encode_i_32(17, serializer);
case PaymentError_SendError(err: final err):
sse_encode_i_32(18, serializer);
case PaymentError_SendError(err: final err):
sse_encode_i_32(19, serializer);
sse_encode_String(err, serializer);
case PaymentError_SignerError(err: final err):
sse_encode_i_32(19, serializer);
sse_encode_i_32(20, serializer);
sse_encode_String(err, serializer);
default:
throw UnimplementedError('');
@@ -5551,8 +5566,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
@protected
void sse_encode_receive_payment_request(ReceivePaymentRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_opt_String(self.description, serializer);
sse_encode_prepare_receive_response(self.prepareResponse, serializer);
sse_encode_opt_String(self.description, serializer);
sse_encode_opt_box_autoadd_bool(self.useDescriptionHash, serializer);
}
@protected

View File

@@ -2308,61 +2308,67 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
wireObj.tag = 8;
return;
}
if (apiObj is PaymentError_InvalidInvoice) {
if (apiObj is PaymentError_InvalidDescription) {
var pre_err = cst_encode_String(apiObj.err);
wireObj.tag = 9;
wireObj.kind.InvalidDescription.err = pre_err;
return;
}
if (apiObj is PaymentError_InvalidInvoice) {
var pre_err = cst_encode_String(apiObj.err);
wireObj.tag = 10;
wireObj.kind.InvalidInvoice.err = pre_err;
return;
}
if (apiObj is PaymentError_InvalidPreimage) {
wireObj.tag = 10;
wireObj.tag = 11;
return;
}
if (apiObj is PaymentError_LwkError) {
var pre_err = cst_encode_String(apiObj.err);
wireObj.tag = 11;
wireObj.tag = 12;
wireObj.kind.LwkError.err = pre_err;
return;
}
if (apiObj is PaymentError_PairsNotFound) {
wireObj.tag = 12;
return;
}
if (apiObj is PaymentError_PaymentTimeout) {
wireObj.tag = 13;
return;
}
if (apiObj is PaymentError_PersistError) {
if (apiObj is PaymentError_PaymentTimeout) {
wireObj.tag = 14;
return;
}
if (apiObj is PaymentError_PersistError) {
wireObj.tag = 15;
return;
}
if (apiObj is PaymentError_ReceiveError) {
var pre_err = cst_encode_String(apiObj.err);
wireObj.tag = 15;
wireObj.tag = 16;
wireObj.kind.ReceiveError.err = pre_err;
return;
}
if (apiObj is PaymentError_Refunded) {
var pre_err = cst_encode_String(apiObj.err);
var pre_refund_tx_id = cst_encode_String(apiObj.refundTxId);
wireObj.tag = 16;
wireObj.tag = 17;
wireObj.kind.Refunded.err = pre_err;
wireObj.kind.Refunded.refund_tx_id = pre_refund_tx_id;
return;
}
if (apiObj is PaymentError_SelfTransferNotSupported) {
wireObj.tag = 17;
wireObj.tag = 18;
return;
}
if (apiObj is PaymentError_SendError) {
var pre_err = cst_encode_String(apiObj.err);
wireObj.tag = 18;
wireObj.tag = 19;
wireObj.kind.SendError.err = pre_err;
return;
}
if (apiObj is PaymentError_SignerError) {
var pre_err = cst_encode_String(apiObj.err);
wireObj.tag = 19;
wireObj.tag = 20;
wireObj.kind.SignerError.err = pre_err;
return;
}
@@ -2452,8 +2458,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void cst_api_fill_to_wire_receive_payment_request(
ReceivePaymentRequest apiObj, wire_cst_receive_payment_request wireObj) {
wireObj.description = cst_encode_opt_String(apiObj.description);
cst_api_fill_to_wire_prepare_receive_response(apiObj.prepareResponse, wireObj.prepare_response);
wireObj.description = cst_encode_opt_String(apiObj.description);
wireObj.use_description_hash = cst_encode_opt_box_autoadd_bool(apiObj.useDescriptionHash);
}
@protected
@@ -4641,9 +4648,11 @@ final class wire_cst_prepare_receive_response extends ffi.Struct {
}
final class wire_cst_receive_payment_request extends ffi.Struct {
external wire_cst_prepare_receive_response prepare_response;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> description;
external wire_cst_prepare_receive_response prepare_response;
external ffi.Pointer<ffi.Bool> use_description_hash;
}
final class wire_cst_refund_request extends ffi.Struct {
@@ -5457,6 +5466,10 @@ final class wire_cst_PaymentError_Generic extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> err;
}
final class wire_cst_PaymentError_InvalidDescription extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> err;
}
final class wire_cst_PaymentError_InvalidInvoice extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> err;
}
@@ -5490,6 +5503,8 @@ final class PaymentErrorKind extends ffi.Union {
external wire_cst_PaymentError_Generic Generic;
external wire_cst_PaymentError_InvalidDescription InvalidDescription;
external wire_cst_PaymentError_InvalidInvoice InvalidInvoice;
external wire_cst_PaymentError_LwkError LwkError;

View File

@@ -844,24 +844,31 @@ class PrepareSendResponse {
/// An argument when calling [crate::sdk::LiquidSdk::receive_payment].
class ReceivePaymentRequest {
final String? description;
final PrepareReceiveResponse prepareResponse;
/// The description for this payment request.
final String? description;
/// If set to true, then the hash of the description will be used.
final bool? useDescriptionHash;
const ReceivePaymentRequest({
this.description,
required this.prepareResponse,
this.description,
this.useDescriptionHash,
});
@override
int get hashCode => description.hashCode ^ prepareResponse.hashCode;
int get hashCode => prepareResponse.hashCode ^ description.hashCode ^ useDescriptionHash.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is ReceivePaymentRequest &&
runtimeType == other.runtimeType &&
prepareResponse == other.prepareResponse &&
description == other.description &&
prepareResponse == other.prepareResponse;
useDescriptionHash == other.useDescriptionHash;
}
/// Returned when calling [crate::sdk::LiquidSdk::receive_payment].

View File

@@ -1559,9 +1559,11 @@ final class wire_cst_prepare_receive_response extends ffi.Struct {
}
final class wire_cst_receive_payment_request extends ffi.Struct {
external wire_cst_prepare_receive_response prepare_response;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> description;
external wire_cst_prepare_receive_response prepare_response;
external ffi.Pointer<ffi.Bool> use_description_hash;
}
final class wire_cst_refund_request extends ffi.Struct {
@@ -2375,6 +2377,10 @@ final class wire_cst_PaymentError_Generic extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> err;
}
final class wire_cst_PaymentError_InvalidDescription extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> err;
}
final class wire_cst_PaymentError_InvalidInvoice extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> err;
}
@@ -2408,6 +2414,8 @@ final class PaymentErrorKind extends ffi.Union {
external wire_cst_PaymentError_Generic Generic;
external wire_cst_PaymentError_InvalidDescription InvalidDescription;
external wire_cst_PaymentError_InvalidInvoice InvalidInvoice;
external wire_cst_PaymentError_LwkError LwkError;

View File

@@ -1602,13 +1602,24 @@ fun asReceivePaymentRequest(receivePaymentRequest: ReadableMap): ReceivePaymentR
}
val prepareResponse = receivePaymentRequest.getMap("prepareResponse")?.let { asPrepareReceiveResponse(it) }!!
val description = if (hasNonNullKey(receivePaymentRequest, "description")) receivePaymentRequest.getString("description") else null
return ReceivePaymentRequest(prepareResponse, description)
val useDescriptionHash =
if (hasNonNullKey(
receivePaymentRequest,
"useDescriptionHash",
)
) {
receivePaymentRequest.getBoolean("useDescriptionHash")
} else {
null
}
return ReceivePaymentRequest(prepareResponse, description, useDescriptionHash)
}
fun readableMapOf(receivePaymentRequest: ReceivePaymentRequest): ReadableMap =
readableMapOf(
"prepareResponse" to readableMapOf(receivePaymentRequest.prepareResponse),
"description" to receivePaymentRequest.description,
"useDescriptionHash" to receivePaymentRequest.useDescriptionHash,
)
fun asReceivePaymentRequestList(arr: ReadableArray): List<ReceivePaymentRequest> {

View File

@@ -1868,14 +1868,22 @@ enum BreezSDKLiquidMapper {
}
description = descriptionTmp
}
var useDescriptionHash: Bool?
if hasNonNilKey(data: receivePaymentRequest, key: "useDescriptionHash") {
guard let useDescriptionHashTmp = receivePaymentRequest["useDescriptionHash"] as? Bool else {
throw SdkError.Generic(message: errUnexpectedValue(fieldName: "useDescriptionHash"))
}
useDescriptionHash = useDescriptionHashTmp
}
return ReceivePaymentRequest(prepareResponse: prepareResponse, description: description)
return ReceivePaymentRequest(prepareResponse: prepareResponse, description: description, useDescriptionHash: useDescriptionHash)
}
static func dictionaryOf(receivePaymentRequest: ReceivePaymentRequest) -> [String: Any?] {
return [
"prepareResponse": dictionaryOf(prepareReceiveResponse: receivePaymentRequest.prepareResponse),
"description": receivePaymentRequest.description == nil ? nil : receivePaymentRequest.description,
"useDescriptionHash": receivePaymentRequest.useDescriptionHash == nil ? nil : receivePaymentRequest.useDescriptionHash,
]
}

View File

@@ -285,6 +285,7 @@ export interface Rate {
export interface ReceivePaymentRequest {
prepareResponse: PrepareReceiveResponse
description?: string
useDescriptionHash?: boolean
}
export interface ReceivePaymentResponse {