Skip to content

Commit

Permalink
Store unblinding data for the tx
Browse files Browse the repository at this point in the history
  • Loading branch information
dangeross committed Dec 6, 2024
1 parent 5f1fda0 commit 58b79f8
Show file tree
Hide file tree
Showing 18 changed files with 109 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ typedef struct wire_cst_payment_details {
typedef struct wire_cst_payment {
struct wire_cst_list_prim_u_8_strict *destination;
struct wire_cst_list_prim_u_8_strict *tx_id;
struct wire_cst_list_prim_u_8_strict *unblinding_data;
uint32_t timestamp;
uint64_t amount_sat;
uint64_t fees_sat;
Expand Down
1 change: 1 addition & 0 deletions lib/bindings/src/breez_sdk_liquid.udl
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ dictionary Payment {
PaymentDetails details;
string? destination = null;
string? tx_id = null;
string? unblinding_data = null;
};

enum PaymentType {
Expand Down
2 changes: 2 additions & 0 deletions lib/core/src/chain_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ impl ChainSwapHandler {
fees_sat: lockup_tx_fees_sat + swap.claim_fees_sat,
payment_type: PaymentType::Send,
is_confirmed: false,
unblinding_data: None,
}, None, None)?;

self.update_swap_info(&ChainSwapUpdate {
Expand Down Expand Up @@ -837,6 +838,7 @@ impl ChainSwapHandler {
fees_sat: 0,
payment_type: PaymentType::Receive,
is_confirmed: false,
unblinding_data: None,
},
None,
None,
Expand Down
7 changes: 7 additions & 0 deletions lib/core/src/frb_generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3445,6 +3445,7 @@ impl SseDecode for crate::model::Payment {
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_destination = <Option<String>>::sse_decode(deserializer);
let mut var_txId = <Option<String>>::sse_decode(deserializer);
let mut var_unblindingData = <Option<String>>::sse_decode(deserializer);
let mut var_timestamp = <u32>::sse_decode(deserializer);
let mut var_amountSat = <u64>::sse_decode(deserializer);
let mut var_feesSat = <u64>::sse_decode(deserializer);
Expand All @@ -3454,6 +3455,7 @@ impl SseDecode for crate::model::Payment {
return crate::model::Payment {
destination: var_destination,
tx_id: var_txId,
unblinding_data: var_unblindingData,
timestamp: var_timestamp,
amount_sat: var_amountSat,
fees_sat: var_feesSat,
Expand Down Expand Up @@ -5455,6 +5457,7 @@ impl flutter_rust_bridge::IntoDart for crate::model::Payment {
[
self.destination.into_into_dart().into_dart(),
self.tx_id.into_into_dart().into_dart(),
self.unblinding_data.into_into_dart().into_dart(),
self.timestamp.into_into_dart().into_dart(),
self.amount_sat.into_into_dart().into_dart(),
self.fees_sat.into_into_dart().into_dart(),
Expand Down Expand Up @@ -7417,6 +7420,7 @@ impl SseEncode for crate::model::Payment {
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<Option<String>>::sse_encode(self.destination, serializer);
<Option<String>>::sse_encode(self.tx_id, serializer);
<Option<String>>::sse_encode(self.unblinding_data, serializer);
<u32>::sse_encode(self.timestamp, serializer);
<u64>::sse_encode(self.amount_sat, serializer);
<u64>::sse_encode(self.fees_sat, serializer);
Expand Down Expand Up @@ -9357,6 +9361,7 @@ mod io {
crate::model::Payment {
destination: self.destination.cst_decode(),
tx_id: self.tx_id.cst_decode(),
unblinding_data: self.unblinding_data.cst_decode(),
timestamp: self.timestamp.cst_decode(),
amount_sat: self.amount_sat.cst_decode(),
fees_sat: self.fees_sat.cst_decode(),
Expand Down Expand Up @@ -10564,6 +10569,7 @@ mod io {
Self {
destination: core::ptr::null_mut(),
tx_id: core::ptr::null_mut(),
unblinding_data: core::ptr::null_mut(),
timestamp: Default::default(),
amount_sat: Default::default(),
fees_sat: Default::default(),
Expand Down Expand Up @@ -12672,6 +12678,7 @@ mod io {
pub struct wire_cst_payment {
destination: *mut wire_cst_list_prim_u_8_strict,
tx_id: *mut wire_cst_list_prim_u_8_strict,
unblinding_data: *mut wire_cst_list_prim_u_8_strict,
timestamp: u32,
amount_sat: u64,
fees_sat: u64,
Expand Down
10 changes: 10 additions & 0 deletions lib/core/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,10 @@ pub struct PaymentTxData {

/// Onchain tx status
pub is_confirmed: bool,

/// Data to use in the `blinded` param when unblinding the transaction in an explorer.
/// See: https://docs.liquid.net/docs/unblinding-transactions
pub unblinding_data: Option<String>,
}

#[derive(Debug, Clone, Serialize)]
Expand Down Expand Up @@ -1269,6 +1273,10 @@ pub struct Payment {

pub tx_id: Option<String>,

/// Data to use in the `blinded` param when unblinding the transaction in an explorer.
/// See: https://docs.liquid.net/docs/unblinding-transactions
pub unblinding_data: Option<String>,

/// Composite timestamp that can be used for sorting or displaying the payment.
///
/// If this payment has an associated swap, it is the swap creation time. Otherwise, the point
Expand Down Expand Up @@ -1320,6 +1328,7 @@ impl Payment {
Payment {
destination: swap.bolt11.clone(),
tx_id: None,
unblinding_data: None,
timestamp: swap.created_at,
amount_sat,
fees_sat: swap.payer_amount_sat - swap.receiver_amount_sat,
Expand All @@ -1345,6 +1354,7 @@ impl Payment {
) -> Payment {
Payment {
tx_id: Some(tx.tx_id),
unblinding_data: tx.unblinding_data,
// When the swap is present and of type send and receive, we retrieve the destination from the invoice.
// If it's a chain swap instead, we use the `claim_address` field from the swap data (either pure Bitcoin or Liquid address).
// Otherwise, we specify the Liquid address (BIP21 or pure), set in `payment_details.address`.
Expand Down
1 change: 1 addition & 0 deletions lib/core/src/persist/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,5 +208,6 @@ pub(crate) fn current_migrations() -> Vec<&'static str> {
data BLOB NOT NULL
) STRICT;",
"ALTER TABLE receive_swaps DROP COLUMN mrh_script_pubkey;",
"ALTER TABLE payment_tx_data ADD COLUMN unblinding_data TEXT;",
]
}
86 changes: 47 additions & 39 deletions lib/core/src/persist/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ impl Persister {
.iter()
.find(|output| output.is_some())
.and_then(|output| output.clone().map(|o| o.script_pubkey.to_hex()));
let unblinding_data = tx
.unblinded_url("")
.replace(&format!("tx/{}#blinded=", tx_id), "");
self.insert_or_update_payment(
PaymentTxData {
tx_id: tx_id.clone(),
Expand All @@ -118,6 +121,7 @@ impl Persister {
false => PaymentType::Send,
},
is_confirmed: is_tx_confirmed,
unblinding_data: Some(unblinding_data),
},
maybe_script_pubkey,
None,
Expand All @@ -138,9 +142,10 @@ impl Persister {
amount_sat,
fees_sat,
payment_type,
is_confirmed
is_confirmed,
unblinding_data
)
VALUES (?, ?, ?, ?, ?, ?)
VALUES (?, ?, ?, ?, ?, ?, ?)
",
(
&ptx.tx_id,
Expand All @@ -149,6 +154,7 @@ impl Persister {
ptx.fees_sat,
ptx.payment_type,
ptx.is_confirmed,
ptx.unblinding_data,
),
)?;

Expand Down Expand Up @@ -207,6 +213,7 @@ impl Persister {
ptx.fees_sat,
ptx.payment_type,
ptx.is_confirmed,
ptx.unblinding_data,
rs.id,
rs.created_at,
rs.invoice,
Expand Down Expand Up @@ -280,47 +287,48 @@ impl Persister {
fees_sat: row.get(3)?,
payment_type: row.get(4)?,
is_confirmed: row.get(5)?,
unblinding_data: row.get(6)?,
}),
_ => None,
};

let maybe_receive_swap_id: Option<String> = row.get(6)?;
let maybe_receive_swap_created_at: Option<u32> = row.get(7)?;
let maybe_receive_swap_invoice: Option<String> = row.get(8)?;
let maybe_receive_swap_payment_hash: Option<String> = row.get(9)?;
let maybe_receive_swap_description: Option<String> = row.get(10)?;
let maybe_receive_swap_preimage: Option<String> = row.get(11)?;
let maybe_receive_swap_payer_amount_sat: Option<u64> = row.get(12)?;
let maybe_receive_swap_receiver_amount_sat: Option<u64> = row.get(13)?;
let maybe_receive_swap_receiver_state: Option<PaymentState> = row.get(14)?;

let maybe_send_swap_id: Option<String> = row.get(15)?;
let maybe_send_swap_created_at: Option<u32> = row.get(16)?;
let maybe_send_swap_invoice: Option<String> = row.get(17)?;
let maybe_send_swap_bolt12_offer: Option<String> = row.get(18)?;
let maybe_send_swap_payment_hash: Option<String> = row.get(19)?;
let maybe_send_swap_description: Option<String> = row.get(20)?;
let maybe_send_swap_preimage: Option<String> = row.get(21)?;
let maybe_send_swap_refund_tx_id: Option<String> = row.get(22)?;
let maybe_send_swap_payer_amount_sat: Option<u64> = row.get(23)?;
let maybe_send_swap_receiver_amount_sat: Option<u64> = row.get(24)?;
let maybe_send_swap_state: Option<PaymentState> = row.get(25)?;

let maybe_chain_swap_id: Option<String> = row.get(26)?;
let maybe_chain_swap_created_at: Option<u32> = row.get(27)?;
let maybe_chain_swap_direction: Option<Direction> = row.get(28)?;
let maybe_chain_swap_preimage: Option<String> = row.get(29)?;
let maybe_chain_swap_description: Option<String> = row.get(30)?;
let maybe_chain_swap_refund_tx_id: Option<String> = row.get(31)?;
let maybe_chain_swap_payer_amount_sat: Option<u64> = row.get(32)?;
let maybe_chain_swap_receiver_amount_sat: Option<u64> = row.get(33)?;
let maybe_chain_swap_claim_address: Option<String> = row.get(34)?;
let maybe_chain_swap_state: Option<PaymentState> = row.get(35)?;

let maybe_swap_refund_tx_amount_sat: Option<u64> = row.get(36)?;

let maybe_payment_details_destination: Option<String> = row.get(37)?;
let maybe_payment_details_description: Option<String> = row.get(38)?;
let maybe_receive_swap_id: Option<String> = row.get(7)?;
let maybe_receive_swap_created_at: Option<u32> = row.get(8)?;
let maybe_receive_swap_invoice: Option<String> = row.get(9)?;
let maybe_receive_swap_payment_hash: Option<String> = row.get(10)?;
let maybe_receive_swap_description: Option<String> = row.get(11)?;
let maybe_receive_swap_preimage: Option<String> = row.get(12)?;
let maybe_receive_swap_payer_amount_sat: Option<u64> = row.get(13)?;
let maybe_receive_swap_receiver_amount_sat: Option<u64> = row.get(14)?;
let maybe_receive_swap_receiver_state: Option<PaymentState> = row.get(15)?;

let maybe_send_swap_id: Option<String> = row.get(16)?;
let maybe_send_swap_created_at: Option<u32> = row.get(17)?;
let maybe_send_swap_invoice: Option<String> = row.get(18)?;
let maybe_send_swap_bolt12_offer: Option<String> = row.get(19)?;
let maybe_send_swap_payment_hash: Option<String> = row.get(20)?;
let maybe_send_swap_description: Option<String> = row.get(21)?;
let maybe_send_swap_preimage: Option<String> = row.get(22)?;
let maybe_send_swap_refund_tx_id: Option<String> = row.get(23)?;
let maybe_send_swap_payer_amount_sat: Option<u64> = row.get(24)?;
let maybe_send_swap_receiver_amount_sat: Option<u64> = row.get(25)?;
let maybe_send_swap_state: Option<PaymentState> = row.get(26)?;

let maybe_chain_swap_id: Option<String> = row.get(27)?;
let maybe_chain_swap_created_at: Option<u32> = row.get(28)?;
let maybe_chain_swap_direction: Option<Direction> = row.get(29)?;
let maybe_chain_swap_preimage: Option<String> = row.get(30)?;
let maybe_chain_swap_description: Option<String> = row.get(31)?;
let maybe_chain_swap_refund_tx_id: Option<String> = row.get(32)?;
let maybe_chain_swap_payer_amount_sat: Option<u64> = row.get(33)?;
let maybe_chain_swap_receiver_amount_sat: Option<u64> = row.get(34)?;
let maybe_chain_swap_claim_address: Option<String> = row.get(35)?;
let maybe_chain_swap_state: Option<PaymentState> = row.get(36)?;

let maybe_swap_refund_tx_amount_sat: Option<u64> = row.get(37)?;

let maybe_payment_details_destination: Option<String> = row.get(38)?;
let maybe_payment_details_description: Option<String> = row.get(39)?;

let (swap, payment_type) = match maybe_receive_swap_id {
Some(receive_swap_id) => (
Expand Down
1 change: 1 addition & 0 deletions lib/core/src/receive_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ impl ReceiveSwapHandler {
fees_sat: 0,
payment_type: PaymentType::Receive,
is_confirmed: false,
unblinding_data: None,
},
None,
None,
Expand Down
1 change: 1 addition & 0 deletions lib/core/src/sdk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,7 @@ impl LiquidSdk {
fees_sat,
payment_type: PaymentType::Send,
is_confirmed: false,
unblinding_data: None,
};

let destination = address_data.to_uri().unwrap_or(address_data.address);
Expand Down
1 change: 1 addition & 0 deletions lib/core/src/send_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ impl SendSwapHandler {
fees_sat: lockup_tx_fees_sat,
payment_type: PaymentType::Send,
is_confirmed: false,
unblinding_data: None,
},
None,
None,
Expand Down
1 change: 1 addition & 0 deletions lib/core/src/test_utils/persist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,5 +133,6 @@ pub(crate) fn new_payment_tx_data(payment_type: PaymentType) -> PaymentTxData {
fees_sat: 0,
payment_type,
is_confirmed: false,
unblinding_data: None,
}
}
18 changes: 11 additions & 7 deletions packages/dart/lib/src/frb_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2470,16 +2470,17 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
Payment dco_decode_payment(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 8) throw Exception('unexpected arr length: expect 8 but see ${arr.length}');
if (arr.length != 9) throw Exception('unexpected arr length: expect 9 but see ${arr.length}');
return Payment(
destination: dco_decode_opt_String(arr[0]),
txId: dco_decode_opt_String(arr[1]),
timestamp: dco_decode_u_32(arr[2]),
amountSat: dco_decode_u_64(arr[3]),
feesSat: dco_decode_u_64(arr[4]),
paymentType: dco_decode_payment_type(arr[5]),
status: dco_decode_payment_state(arr[6]),
details: dco_decode_payment_details(arr[7]),
unblindingData: dco_decode_opt_String(arr[2]),
timestamp: dco_decode_u_32(arr[3]),
amountSat: dco_decode_u_64(arr[4]),
feesSat: dco_decode_u_64(arr[5]),
paymentType: dco_decode_payment_type(arr[6]),
status: dco_decode_payment_state(arr[7]),
details: dco_decode_payment_details(arr[8]),
);
}

Expand Down Expand Up @@ -4444,6 +4445,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_destination = sse_decode_opt_String(deserializer);
var var_txId = sse_decode_opt_String(deserializer);
var var_unblindingData = sse_decode_opt_String(deserializer);
var var_timestamp = sse_decode_u_32(deserializer);
var var_amountSat = sse_decode_u_64(deserializer);
var var_feesSat = sse_decode_u_64(deserializer);
Expand All @@ -4453,6 +4455,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return Payment(
destination: var_destination,
txId: var_txId,
unblindingData: var_unblindingData,
timestamp: var_timestamp,
amountSat: var_amountSat,
feesSat: var_feesSat,
Expand Down Expand Up @@ -6303,6 +6306,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_opt_String(self.destination, serializer);
sse_encode_opt_String(self.txId, serializer);
sse_encode_opt_String(self.unblindingData, serializer);
sse_encode_u_32(self.timestamp, serializer);
sse_encode_u_64(self.amountSat, serializer);
sse_encode_u_64(self.feesSat, serializer);
Expand Down
3 changes: 3 additions & 0 deletions packages/dart/lib/src/frb_generated.io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2673,6 +2673,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
void cst_api_fill_to_wire_payment(Payment apiObj, wire_cst_payment wireObj) {
wireObj.destination = cst_encode_opt_String(apiObj.destination);
wireObj.tx_id = cst_encode_opt_String(apiObj.txId);
wireObj.unblinding_data = cst_encode_opt_String(apiObj.unblindingData);
wireObj.timestamp = cst_encode_u_32(apiObj.timestamp);
wireObj.amount_sat = cst_encode_u_64(apiObj.amountSat);
wireObj.fees_sat = cst_encode_u_64(apiObj.feesSat);
Expand Down Expand Up @@ -5840,6 +5841,8 @@ final class wire_cst_payment extends ffi.Struct {

external ffi.Pointer<wire_cst_list_prim_u_8_strict> tx_id;

external ffi.Pointer<wire_cst_list_prim_u_8_strict> unblinding_data;

@ffi.Uint32()
external int timestamp;

Expand Down
7 changes: 7 additions & 0 deletions packages/dart/lib/src/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,10 @@ class Payment {
final String? destination;
final String? txId;

/// Data to use in the `blinded` param when unblinding the transaction in an explorer.
/// See: https://docs.liquid.net/docs/unblinding-transactions
final String? unblindingData;

/// Composite timestamp that can be used for sorting or displaying the payment.
///
/// If this payment has an associated swap, it is the swap creation time. Otherwise, the point
Expand Down Expand Up @@ -575,6 +579,7 @@ class Payment {
const Payment({
this.destination,
this.txId,
this.unblindingData,
required this.timestamp,
required this.amountSat,
required this.feesSat,
Expand All @@ -587,6 +592,7 @@ class Payment {
int get hashCode =>
destination.hashCode ^
txId.hashCode ^
unblindingData.hashCode ^
timestamp.hashCode ^
amountSat.hashCode ^
feesSat.hashCode ^
Expand All @@ -601,6 +607,7 @@ class Payment {
runtimeType == other.runtimeType &&
destination == other.destination &&
txId == other.txId &&
unblindingData == other.unblindingData &&
timestamp == other.timestamp &&
amountSat == other.amountSat &&
feesSat == other.feesSat &&
Expand Down
Loading

0 comments on commit 58b79f8

Please sign in to comment.