mirror of
https://github.com/aljazceru/breez-sdk-liquid.git
synced 2025-12-23 00:44:26 +01:00
Payment lifecycle (#184)
* Rename swap tables: remove ongoing_ prefix * Add swap status enums and filtering * Swap-in: add claim_txid * Swap-out: add claim_txid * resolve_swap: Don't remove swap when complete * Fixups after rebase * Remove unused method * Consider payment as pending based on confirmations An onchain payment with no confirmations is considered pending. The previous logic of converting pending swaps into pending payments is removed, since we may have pending swaps that should not result in pending payments (for example on Receive, before the invoice is paid). * Fix swap-in query * GetInfoResponse: fix balance, include pending * Remove unused method * Re-generate flutter bridge files * Re-generate RN bindings * Fix payment_type detection in list_payments * Send: persist to DB when claim tx is seen * Receive: fix occasional error when broadcasting claim * Remove fixed TODO * Receive: only rescan on testnet, where Electrum is used to broadcast * Log more details when broadcasting fails * Improve AlreadyClaimed error detection and handling * Rename SubmarineSwapStatus::Initial to Created * Split pending payment types into separate field status * Rename swap status enums * Fix INSERT query * Bump lwk libraries * Simplify Receive try_handle_reverse_swap_status loop * Change resolve_swap to insert_or_update_payment * Refactor payment data persistence * Remove unused dependency * Bump LWK dependencies * Rename reconcile_payments_with_onchain * Rename try_claim_v2 * Rename address() to next_unused_address() * Move all claim persistence writes in try_claim * Flatten Payment struct * Re-generate bindings * Expose sync() in service interface * Set Send ws stream as nonblocking, use singleton stream * Send_payment: sync() before handling new state * Sync() on sdk.connect() * Remove unused args from list_payments() * Receive: rename DB field redeem_script to response JSON * Convert to and from internal structs to persist CreateResponse JSON * De-duplicate internal CreateResponse structs to prevent storing same field twice * Schedule a periodic sync() thread on startup * Persist swap states and add methods to transition between them * Handle unwrap() when subscribing for WS updates * Status Stream: handle remaining unwraps() and TODOs * Consolidate status transitions into two SDK methods * Status Stream: reconnect and resume tracking on disconnect * Remove superfluous TODO * Send swaps: correctly transition to Complete even if app killed during send_payment() * State transitions: Move SQL queries to persistence layer * Send: handle edge TransactionClaimed edge-case * Send: mark as Complete after we check the preimage * Send: remove marking as Complete on TransactionClaimed
This commit is contained in:
@@ -50,9 +50,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
@protected
|
||||
RestoreRequest dco_decode_box_autoadd_restore_request(dynamic raw);
|
||||
|
||||
@protected
|
||||
int dco_decode_box_autoadd_u_32(dynamic raw);
|
||||
|
||||
@protected
|
||||
int dco_decode_box_autoadd_u_64(dynamic raw);
|
||||
|
||||
@@ -78,10 +75,10 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
Network dco_decode_network(dynamic raw);
|
||||
|
||||
@protected
|
||||
String? dco_decode_opt_String(dynamic raw);
|
||||
NewSwapState dco_decode_new_swap_state(dynamic raw);
|
||||
|
||||
@protected
|
||||
int? dco_decode_opt_box_autoadd_u_32(dynamic raw);
|
||||
String? dco_decode_opt_String(dynamic raw);
|
||||
|
||||
@protected
|
||||
int? dco_decode_opt_box_autoadd_u_64(dynamic raw);
|
||||
@@ -158,9 +155,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
@protected
|
||||
RestoreRequest sse_decode_box_autoadd_restore_request(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int sse_decode_box_autoadd_u_32(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int sse_decode_box_autoadd_u_64(SseDeserializer deserializer);
|
||||
|
||||
@@ -186,10 +180,10 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
Network sse_decode_network(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
String? sse_decode_opt_String(SseDeserializer deserializer);
|
||||
NewSwapState sse_decode_new_swap_state(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int? sse_decode_opt_box_autoadd_u_32(SseDeserializer deserializer);
|
||||
String? sse_decode_opt_String(SseDeserializer deserializer);
|
||||
|
||||
@protected
|
||||
int? sse_decode_opt_box_autoadd_u_64(SseDeserializer deserializer);
|
||||
@@ -308,12 +302,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@protected
|
||||
ffi.Pointer<ffi.Uint32> cst_encode_box_autoadd_u_32(int raw) {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
return wire.cst_new_box_autoadd_u_32(cst_encode_u_32(raw));
|
||||
}
|
||||
|
||||
@protected
|
||||
ffi.Pointer<ffi.Uint64> cst_encode_box_autoadd_u_64(int raw) {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
@@ -344,12 +332,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
return raw == null ? ffi.nullptr : cst_encode_String(raw);
|
||||
}
|
||||
|
||||
@protected
|
||||
ffi.Pointer<ffi.Uint32> cst_encode_opt_box_autoadd_u_32(int? raw) {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
return raw == null ? ffi.nullptr : cst_encode_box_autoadd_u_32(raw);
|
||||
}
|
||||
|
||||
@protected
|
||||
ffi.Pointer<ffi.Uint64> cst_encode_opt_box_autoadd_u_64(int? raw) {
|
||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||
@@ -419,17 +401,20 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
@protected
|
||||
void cst_api_fill_to_wire_get_info_response(GetInfoResponse apiObj, wire_cst_get_info_response wireObj) {
|
||||
wireObj.balance_sat = cst_encode_u_64(apiObj.balanceSat);
|
||||
wireObj.pending_send_sat = cst_encode_u_64(apiObj.pendingSendSat);
|
||||
wireObj.pending_receive_sat = cst_encode_u_64(apiObj.pendingReceiveSat);
|
||||
wireObj.pubkey = cst_encode_String(apiObj.pubkey);
|
||||
}
|
||||
|
||||
@protected
|
||||
void cst_api_fill_to_wire_payment(Payment apiObj, wire_cst_payment wireObj) {
|
||||
wireObj.id = cst_encode_opt_String(apiObj.id);
|
||||
wireObj.timestamp = cst_encode_opt_box_autoadd_u_32(apiObj.timestamp);
|
||||
wireObj.tx_id = cst_encode_String(apiObj.txId);
|
||||
wireObj.swap_id = cst_encode_opt_String(apiObj.swapId);
|
||||
wireObj.timestamp = cst_encode_u_32(apiObj.timestamp);
|
||||
wireObj.amount_sat = cst_encode_u_64(apiObj.amountSat);
|
||||
wireObj.fees_sat = cst_encode_opt_box_autoadd_u_64(apiObj.feesSat);
|
||||
wireObj.payment_type = cst_encode_payment_type(apiObj.paymentType);
|
||||
wireObj.invoice = cst_encode_opt_String(apiObj.invoice);
|
||||
wireObj.status = cst_encode_new_swap_state(apiObj.status);
|
||||
}
|
||||
|
||||
@protected
|
||||
@@ -480,10 +465,10 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
}
|
||||
if (apiObj is PaymentError_Refunded) {
|
||||
var pre_err = cst_encode_String(apiObj.err);
|
||||
var pre_txid = cst_encode_String(apiObj.txid);
|
||||
var pre_refund_tx_id = cst_encode_String(apiObj.refundTxId);
|
||||
wireObj.tag = 10;
|
||||
wireObj.kind.Refunded.err = pre_err;
|
||||
wireObj.kind.Refunded.txid = pre_txid;
|
||||
wireObj.kind.Refunded.refund_tx_id = pre_refund_tx_id;
|
||||
return;
|
||||
}
|
||||
if (apiObj is PaymentError_SendError) {
|
||||
@@ -553,6 +538,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
@protected
|
||||
int cst_encode_network(Network raw);
|
||||
|
||||
@protected
|
||||
int cst_encode_new_swap_state(NewSwapState raw);
|
||||
|
||||
@protected
|
||||
int cst_encode_payment_type(PaymentType raw);
|
||||
|
||||
@@ -595,9 +583,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
@protected
|
||||
void sse_encode_box_autoadd_restore_request(RestoreRequest self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_box_autoadd_u_32(int self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_box_autoadd_u_64(int self, SseSerializer serializer);
|
||||
|
||||
@@ -623,10 +608,10 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
||||
void sse_encode_network(Network self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_opt_String(String? self, SseSerializer serializer);
|
||||
void sse_encode_new_swap_state(NewSwapState self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_opt_box_autoadd_u_32(int? self, SseSerializer serializer);
|
||||
void sse_encode_opt_String(String? self, SseSerializer serializer);
|
||||
|
||||
@protected
|
||||
void sse_encode_opt_box_autoadd_u_64(int? self, SseSerializer serializer);
|
||||
@@ -767,20 +752,15 @@ class RustLibWire implements BaseWire {
|
||||
|
||||
void wire_list_payments(
|
||||
int port_,
|
||||
bool with_scan,
|
||||
bool include_pending,
|
||||
) {
|
||||
return _wire_list_payments(
|
||||
port_,
|
||||
with_scan,
|
||||
include_pending,
|
||||
);
|
||||
}
|
||||
|
||||
late final _wire_list_paymentsPtr =
|
||||
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int64, ffi.Bool, ffi.Bool)>>(
|
||||
'frbgen_breez_liquid_wire_list_payments');
|
||||
late final _wire_list_payments = _wire_list_paymentsPtr.asFunction<void Function(int, bool, bool)>();
|
||||
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int64)>>('frbgen_breez_liquid_wire_list_payments');
|
||||
late final _wire_list_payments = _wire_list_paymentsPtr.asFunction<void Function(int)>();
|
||||
|
||||
void wire_prepare_receive_payment(
|
||||
int port_,
|
||||
@@ -932,20 +912,6 @@ class RustLibWire implements BaseWire {
|
||||
late final _cst_new_box_autoadd_restore_request =
|
||||
_cst_new_box_autoadd_restore_requestPtr.asFunction<ffi.Pointer<wire_cst_restore_request> Function()>();
|
||||
|
||||
ffi.Pointer<ffi.Uint32> cst_new_box_autoadd_u_32(
|
||||
int value,
|
||||
) {
|
||||
return _cst_new_box_autoadd_u_32(
|
||||
value,
|
||||
);
|
||||
}
|
||||
|
||||
late final _cst_new_box_autoadd_u_32Ptr =
|
||||
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Uint32> Function(ffi.Uint32)>>(
|
||||
'frbgen_breez_liquid_cst_new_box_autoadd_u_32');
|
||||
late final _cst_new_box_autoadd_u_32 =
|
||||
_cst_new_box_autoadd_u_32Ptr.asFunction<ffi.Pointer<ffi.Uint32> Function(int)>();
|
||||
|
||||
ffi.Pointer<ffi.Uint64> cst_new_box_autoadd_u_64(
|
||||
int value,
|
||||
) {
|
||||
@@ -1055,9 +1021,12 @@ final class wire_cst_prepare_send_response extends ffi.Struct {
|
||||
}
|
||||
|
||||
final class wire_cst_payment extends ffi.Struct {
|
||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> id;
|
||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> tx_id;
|
||||
|
||||
external ffi.Pointer<ffi.Uint32> timestamp;
|
||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> swap_id;
|
||||
|
||||
@ffi.Uint32()
|
||||
external int timestamp;
|
||||
|
||||
@ffi.Uint64()
|
||||
external int amount_sat;
|
||||
@@ -1067,7 +1036,8 @@ final class wire_cst_payment extends ffi.Struct {
|
||||
@ffi.Int32()
|
||||
external int payment_type;
|
||||
|
||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> invoice;
|
||||
@ffi.Int32()
|
||||
external int status;
|
||||
}
|
||||
|
||||
final class wire_cst_list_payment extends ffi.Struct {
|
||||
@@ -1081,6 +1051,12 @@ final class wire_cst_get_info_response extends ffi.Struct {
|
||||
@ffi.Uint64()
|
||||
external int balance_sat;
|
||||
|
||||
@ffi.Uint64()
|
||||
external int pending_send_sat;
|
||||
|
||||
@ffi.Uint64()
|
||||
external int pending_receive_sat;
|
||||
|
||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> pubkey;
|
||||
}
|
||||
|
||||
@@ -1095,7 +1071,7 @@ final class wire_cst_PaymentError_LwkError extends ffi.Struct {
|
||||
final class wire_cst_PaymentError_Refunded extends ffi.Struct {
|
||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> err;
|
||||
|
||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> txid;
|
||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> refund_tx_id;
|
||||
}
|
||||
|
||||
final class wire_cst_PaymentError_SendError extends ffi.Struct {
|
||||
|
||||
Reference in New Issue
Block a user