Expose real time synced event (#800)

This commit is contained in:
Daniel Granhão
2025-03-24 11:46:02 +00:00
committed by GitHub
parent 3088526bdf
commit 2952b6133e
14 changed files with 225 additions and 35 deletions

View File

@@ -614,6 +614,10 @@ typedef struct wire_cst_SdkEvent_PaymentWaitingFeeAcceptance {
struct wire_cst_payment *details;
} wire_cst_SdkEvent_PaymentWaitingFeeAcceptance;
typedef struct wire_cst_SdkEvent_DataSynced {
bool did_pull_new_records;
} wire_cst_SdkEvent_DataSynced;
typedef union SdkEventKind {
struct wire_cst_SdkEvent_PaymentFailed PaymentFailed;
struct wire_cst_SdkEvent_PaymentPending PaymentPending;
@@ -623,6 +627,7 @@ typedef union SdkEventKind {
struct wire_cst_SdkEvent_PaymentSucceeded PaymentSucceeded;
struct wire_cst_SdkEvent_PaymentWaitingConfirmation PaymentWaitingConfirmation;
struct wire_cst_SdkEvent_PaymentWaitingFeeAcceptance PaymentWaitingFeeAcceptance;
struct wire_cst_SdkEvent_DataSynced DataSynced;
} SdkEventKind;
typedef struct wire_cst_sdk_event {

View File

@@ -1,5 +1,6 @@
.swiftpm/
.build/
.index-build/
*.xcodeproj
*.podspec
Sources/BreezSDKLiquid/BreezSDKLiquid.swift

View File

@@ -690,6 +690,7 @@ interface SdkEvent {
PaymentWaitingConfirmation(Payment details);
PaymentWaitingFeeAcceptance(Payment details);
Synced();
DataSynced(boolean did_pull_new_records);
};
callback interface EventListener {

View File

@@ -4545,6 +4545,12 @@ impl SseDecode for crate::model::SdkEvent {
8 => {
return crate::model::SdkEvent::Synced;
}
9 => {
let mut var_didPullNewRecords = <bool>::sse_decode(deserializer);
return crate::model::SdkEvent::DataSynced {
did_pull_new_records: var_didPullNewRecords,
};
}
_ => {
unimplemented!("");
}
@@ -6999,6 +7005,13 @@ impl flutter_rust_bridge::IntoDart for crate::model::SdkEvent {
[7.into_dart(), details.into_into_dart().into_dart()].into_dart()
}
crate::model::SdkEvent::Synced => [8.into_dart()].into_dart(),
crate::model::SdkEvent::DataSynced {
did_pull_new_records,
} => [
9.into_dart(),
did_pull_new_records.into_into_dart().into_dart(),
]
.into_dart(),
_ => {
unimplemented!("");
}
@@ -9057,6 +9070,12 @@ impl SseEncode for crate::model::SdkEvent {
crate::model::SdkEvent::Synced => {
<i32>::sse_encode(8, serializer);
}
crate::model::SdkEvent::DataSynced {
did_pull_new_records,
} => {
<i32>::sse_encode(9, serializer);
<bool>::sse_encode(did_pull_new_records, serializer);
}
_ => {
unimplemented!("");
}
@@ -11248,6 +11267,12 @@ mod io {
}
}
8 => crate::model::SdkEvent::Synced,
9 => {
let ans = unsafe { self.kind.DataSynced };
crate::model::SdkEvent::DataSynced {
did_pull_new_records: ans.did_pull_new_records.cst_decode(),
}
}
_ => unreachable!(),
}
}
@@ -14930,6 +14955,7 @@ mod io {
PaymentSucceeded: wire_cst_SdkEvent_PaymentSucceeded,
PaymentWaitingConfirmation: wire_cst_SdkEvent_PaymentWaitingConfirmation,
PaymentWaitingFeeAcceptance: wire_cst_SdkEvent_PaymentWaitingFeeAcceptance,
DataSynced: wire_cst_SdkEvent_DataSynced,
nil__: (),
}
#[repr(C)]
@@ -14974,6 +15000,11 @@ mod io {
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_SdkEvent_DataSynced {
did_pull_new_records: bool,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_send_destination {
tag: i32,
kind: SendDestinationKind,

View File

@@ -295,15 +295,37 @@ pub trait EventListener: MaybeSend + MaybeSync {
/// to listen for emitted events.
#[derive(Clone, Debug, PartialEq)]
pub enum SdkEvent {
PaymentFailed { details: Payment },
PaymentPending { details: Payment },
PaymentRefundable { details: Payment },
PaymentRefunded { details: Payment },
PaymentRefundPending { details: Payment },
PaymentSucceeded { details: Payment },
PaymentWaitingConfirmation { details: Payment },
PaymentWaitingFeeAcceptance { details: Payment },
PaymentFailed {
details: Payment,
},
PaymentPending {
details: Payment,
},
PaymentRefundable {
details: Payment,
},
PaymentRefunded {
details: Payment,
},
PaymentRefundPending {
details: Payment,
},
PaymentSucceeded {
details: Payment,
},
PaymentWaitingConfirmation {
details: Payment,
},
PaymentWaitingFeeAcceptance {
details: Payment,
},
/// Synced with mempool and onchain data
Synced,
/// Synced with real-time data sync
DataSynced {
/// Indicates new data was pulled from other instances.
did_pull_new_records: bool,
},
}
#[derive(thiserror::Error, Debug)]

View File

@@ -526,9 +526,11 @@ impl LiquidSdk {
"Received sync event: pulled {} records, pushed {} records",
data.pulled_records_count, data.pushed_records_count
);
if data.pulled_records_count > 0 {
let did_pull_new_records = data.pulled_records_count > 0;
if did_pull_new_records {
subscription_handler.subscribe_swaps().await;
}
cloned.notify_event_listeners(SdkEvent::DataSynced {did_pull_new_records}).await
}
}
}
@@ -682,9 +684,8 @@ impl LiquidSdk {
});
}
async fn notify_event_listeners(&self, e: SdkEvent) -> Result<()> {
async fn notify_event_listeners(&self, e: SdkEvent) {
self.event_manager.notify(e).await;
Ok(())
}
/// Adds an event listener to the [LiquidSdk] instance, where all [SdkEvent]'s will be emitted to.
@@ -717,7 +718,7 @@ impl LiquidSdk {
self.notify_event_listeners(SdkEvent::PaymentSucceeded {
details: payment,
})
.await?
.await
}
Pending => {
match &payment.details.get_swap_id() {
@@ -730,13 +731,13 @@ impl LiquidSdk {
details: payment,
},
)
.await?
.await
} else {
// The lockup tx is in the mempool/confirmed
self.notify_event_listeners(SdkEvent::PaymentPending {
details: payment,
})
.await?
.await
}
}
Swap::Receive(ReceiveSwap {
@@ -751,13 +752,13 @@ impl LiquidSdk {
details: payment,
},
)
.await?
.await
} else {
// The lockup tx is in the mempool/confirmed
self.notify_event_listeners(SdkEvent::PaymentPending {
details: payment,
})
.await?
.await
}
}
Swap::Send(_) => {
@@ -765,7 +766,7 @@ impl LiquidSdk {
self.notify_event_listeners(SdkEvent::PaymentPending {
details: payment,
})
.await?
.await
}
},
// Here we probably have a liquid address payment so we emit PaymentWaitingConfirmation
@@ -773,7 +774,7 @@ impl LiquidSdk {
self.notify_event_listeners(
SdkEvent::PaymentWaitingConfirmation { details: payment },
)
.await?
.await
}
};
}
@@ -794,34 +795,34 @@ impl LiquidSdk {
self.notify_event_listeners(SdkEvent::PaymentWaitingFeeAcceptance {
details: payment,
})
.await?;
.await;
}
Refundable => {
self.notify_event_listeners(SdkEvent::PaymentRefundable {
details: payment,
})
.await?
.await
}
RefundPending => {
// The swap state has changed to RefundPending
self.notify_event_listeners(SdkEvent::PaymentRefundPending {
details: payment,
})
.await?
.await
}
Failed => match payment.payment_type {
PaymentType::Receive => {
self.notify_event_listeners(SdkEvent::PaymentFailed {
details: payment,
})
.await?
.await
}
PaymentType::Send => {
// The refund tx is confirmed
self.notify_event_listeners(SdkEvent::PaymentRefunded {
details: payment,
})
.await?
.await
}
},
_ => (),
@@ -3343,7 +3344,7 @@ impl LiquidSdk {
let duration_ms = Instant::now().duration_since(t0).as_millis();
info!("Synchronized (partial: {partial_sync}) with mempool and onchain data ({duration_ms} ms)");
self.notify_event_listeners(SdkEvent::Synced).await?;
self.notify_event_listeners(SdkEvent::Synced).await;
Ok(())
}

View File

@@ -3169,6 +3169,8 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return SdkEvent_PaymentWaitingFeeAcceptance(details: dco_decode_box_autoadd_payment(raw[1]));
case 8:
return SdkEvent_Synced();
case 9:
return SdkEvent_DataSynced(didPullNewRecords: dco_decode_bool(raw[1]));
default:
throw Exception("unreachable");
}
@@ -5540,6 +5542,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return SdkEvent_PaymentWaitingFeeAcceptance(details: var_details);
case 8:
return SdkEvent_Synced();
case 9:
var var_didPullNewRecords = sse_decode_bool(deserializer);
return SdkEvent_DataSynced(didPullNewRecords: var_didPullNewRecords);
default:
throw UnimplementedError('');
}
@@ -7676,6 +7681,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_box_autoadd_payment(details, serializer);
case SdkEvent_Synced():
sse_encode_i_32(8, serializer);
case SdkEvent_DataSynced(didPullNewRecords: final didPullNewRecords):
sse_encode_i_32(9, serializer);
sse_encode_bool(didPullNewRecords, serializer);
}
}

View File

@@ -3809,6 +3809,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
wireObj.tag = 8;
return;
}
if (apiObj is SdkEvent_DataSynced) {
var pre_did_pull_new_records = cst_encode_bool(apiObj.didPullNewRecords);
wireObj.tag = 9;
wireObj.kind.DataSynced.did_pull_new_records = pre_did_pull_new_records;
return;
}
}
@protected
@@ -7018,6 +7024,11 @@ final class wire_cst_SdkEvent_PaymentWaitingFeeAcceptance extends ffi.Struct {
external ffi.Pointer<wire_cst_payment> details;
}
final class wire_cst_SdkEvent_DataSynced extends ffi.Struct {
@ffi.Bool()
external bool did_pull_new_records;
}
final class SdkEventKind extends ffi.Union {
external wire_cst_SdkEvent_PaymentFailed PaymentFailed;
@@ -7034,6 +7045,8 @@ final class SdkEventKind extends ffi.Union {
external wire_cst_SdkEvent_PaymentWaitingConfirmation PaymentWaitingConfirmation;
external wire_cst_SdkEvent_PaymentWaitingFeeAcceptance PaymentWaitingFeeAcceptance;
external wire_cst_SdkEvent_DataSynced DataSynced;
}
final class wire_cst_sdk_event extends ffi.Struct {

View File

@@ -1570,7 +1570,15 @@ sealed class SdkEvent with _$SdkEvent {
SdkEvent_PaymentWaitingConfirmation;
const factory SdkEvent.paymentWaitingFeeAcceptance({required Payment details}) =
SdkEvent_PaymentWaitingFeeAcceptance;
/// Synced with mempool and onchain data
const factory SdkEvent.synced() = SdkEvent_Synced;
/// Synced with real-time data sync
const factory SdkEvent.dataSynced({
/// Indicates new data was pulled from other instances.
required bool didPullNewRecords,
}) = SdkEvent_DataSynced;
}
@freezed

View File

@@ -1857,6 +1857,73 @@ String toString() {
/// @nodoc
class SdkEvent_DataSynced extends SdkEvent {
const SdkEvent_DataSynced({required this.didPullNewRecords}): super._();
/// Indicates new data was pulled from other instances.
final bool didPullNewRecords;
/// Create a copy of SdkEvent
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$SdkEvent_DataSyncedCopyWith<SdkEvent_DataSynced> get copyWith => _$SdkEvent_DataSyncedCopyWithImpl<SdkEvent_DataSynced>(this, _$identity);
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is SdkEvent_DataSynced&&(identical(other.didPullNewRecords, didPullNewRecords) || other.didPullNewRecords == didPullNewRecords));
}
@override
int get hashCode => Object.hash(runtimeType,didPullNewRecords);
@override
String toString() {
return 'SdkEvent.dataSynced(didPullNewRecords: $didPullNewRecords)';
}
}
/// @nodoc
abstract mixin class $SdkEvent_DataSyncedCopyWith<$Res> implements $SdkEventCopyWith<$Res> {
factory $SdkEvent_DataSyncedCopyWith(SdkEvent_DataSynced value, $Res Function(SdkEvent_DataSynced) _then) = _$SdkEvent_DataSyncedCopyWithImpl;
@useResult
$Res call({
bool didPullNewRecords
});
}
/// @nodoc
class _$SdkEvent_DataSyncedCopyWithImpl<$Res>
implements $SdkEvent_DataSyncedCopyWith<$Res> {
_$SdkEvent_DataSyncedCopyWithImpl(this._self, this._then);
final SdkEvent_DataSynced _self;
final $Res Function(SdkEvent_DataSynced) _then;
/// Create a copy of SdkEvent
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') $Res call({Object? didPullNewRecords = null,}) {
return _then(SdkEvent_DataSynced(
didPullNewRecords: null == didPullNewRecords ? _self.didPullNewRecords : didPullNewRecords // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
/// @nodoc
mixin _$SendDestination {

View File

@@ -4953,6 +4953,11 @@ final class wire_cst_SdkEvent_PaymentWaitingFeeAcceptance extends ffi.Struct {
external ffi.Pointer<wire_cst_payment> details;
}
final class wire_cst_SdkEvent_DataSynced extends ffi.Struct {
@ffi.Bool()
external bool did_pull_new_records;
}
final class SdkEventKind extends ffi.Union {
external wire_cst_SdkEvent_PaymentFailed PaymentFailed;
@@ -4969,6 +4974,8 @@ final class SdkEventKind extends ffi.Union {
external wire_cst_SdkEvent_PaymentWaitingConfirmation PaymentWaitingConfirmation;
external wire_cst_SdkEvent_PaymentWaitingFeeAcceptance PaymentWaitingFeeAcceptance;
external wire_cst_SdkEvent_DataSynced DataSynced;
}
final class wire_cst_sdk_event extends ffi.Struct {

View File

@@ -3715,6 +3715,10 @@ fun asSdkEvent(sdkEvent: ReadableMap): SdkEvent? {
if (type == "synced") {
return SdkEvent.Synced
}
if (type == "dataSynced") {
val didPullNewRecords = sdkEvent.getBoolean("didPullNewRecords")
return SdkEvent.DataSynced(didPullNewRecords)
}
return null
}
@@ -3756,6 +3760,10 @@ fun readableMapOf(sdkEvent: SdkEvent): ReadableMap? {
is SdkEvent.Synced -> {
pushToMap(map, "type", "synced")
}
is SdkEvent.DataSynced -> {
pushToMap(map, "type", "dataSynced")
pushToMap(map, "didPullNewRecords", sdkEvent.didPullNewRecords)
}
}
return map
}

View File

@@ -4623,6 +4623,12 @@ enum BreezSDKLiquidMapper {
if type == "synced" {
return SdkEvent.synced
}
if type == "dataSynced" {
guard let _didPullNewRecords = sdkEvent["didPullNewRecords"] as? Bool else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "didPullNewRecords", typeName: "SdkEvent"))
}
return SdkEvent.dataSynced(didPullNewRecords: _didPullNewRecords)
}
throw SdkError.Generic(message: "Unexpected type \(type) for enum SdkEvent")
}
@@ -4697,6 +4703,14 @@ enum BreezSDKLiquidMapper {
return [
"type": "synced",
]
case let .dataSynced(
didPullNewRecords
):
return [
"type": "dataSynced",
"didPullNewRecords": didPullNewRecords,
]
}
}

View File

@@ -759,7 +759,8 @@ export enum SdkEventVariant {
PAYMENT_SUCCEEDED = "paymentSucceeded",
PAYMENT_WAITING_CONFIRMATION = "paymentWaitingConfirmation",
PAYMENT_WAITING_FEE_ACCEPTANCE = "paymentWaitingFeeAcceptance",
SYNCED = "synced"
SYNCED = "synced",
DATA_SYNCED = "dataSynced"
}
export type SdkEvent = {
@@ -788,6 +789,9 @@ export type SdkEvent = {
details: Payment
} | {
type: SdkEventVariant.SYNCED
} | {
type: SdkEventVariant.DATA_SYNCED,
didPullNewRecords: boolean
}
export enum SendDestinationVariant {