Add option to specify backup path (#228)

* feat: add backup_path to backup method

* Re-generate bindings with flutter_rust_bridge`@ 2.0.0-dev.35

* Rebased on main

* Update backup path description

---------

Co-authored-by: ok300 <106775972+ok300@users.noreply.github.com>
This commit is contained in:
yse
2024-05-27 21:01:49 +02:00
committed by GitHub
parent 6ef5701660
commit 2fcefee45e
21 changed files with 366 additions and 58 deletions

View File

@@ -43,7 +43,10 @@ pub(crate) enum Command {
/// Empties the encrypted transaction cache
EmptyCache,
/// Backs up the current pending swaps
Backup,
Backup {
#[arg(short, long)]
backup_path: Option<String>,
},
/// Retrieve a list of backups
Restore {
#[arg(short, long)]
@@ -159,8 +162,8 @@ pub(crate) async fn handle_command(
sdk.empty_wallet_cache()?;
command_result!("Cache emptied successfully")
}
Command::Backup => {
sdk.backup()?;
Command::Backup { backup_path } => {
sdk.backup(BackupRequest { backup_path })?;
command_result!("Backup created successfully!")
}
Command::Restore { backup_path } => {

View File

@@ -25,6 +25,10 @@ typedef struct wire_cst_list_prim_u_8_strict {
int32_t len;
} wire_cst_list_prim_u_8_strict;
typedef struct wire_cst_backup_request {
struct wire_cst_list_prim_u_8_strict *backup_path;
} wire_cst_backup_request;
typedef struct wire_cst_get_info_request {
bool with_scan;
} wire_cst_get_info_request;
@@ -179,7 +183,8 @@ void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_add_event_liste
struct wire_cst_list_prim_u_8_strict *listener);
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup(int64_t port_,
uintptr_t that);
uintptr_t that,
struct wire_cst_backup_request *req);
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_empty_wallet_cache(int64_t port_,
uintptr_t that);
@@ -221,6 +226,8 @@ void frbgen_breez_liquid_rust_arc_increment_strong_count_RustOpaque_flutter_rust
void frbgen_breez_liquid_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(const void *ptr);
struct wire_cst_backup_request *frbgen_breez_liquid_cst_new_box_autoadd_backup_request(void);
struct wire_cst_connect_request *frbgen_breez_liquid_cst_new_box_autoadd_connect_request(void);
struct wire_cst_get_info_request *frbgen_breez_liquid_cst_new_box_autoadd_get_info_request(void);
@@ -244,6 +251,7 @@ struct wire_cst_list_payment *frbgen_breez_liquid_cst_new_list_payment(int32_t l
struct wire_cst_list_prim_u_8_strict *frbgen_breez_liquid_cst_new_list_prim_u_8_strict(int32_t len);
static int64_t dummy_method_to_enforce_bundling(void) {
int64_t dummy_var = 0;
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_backup_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_connect_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_get_info_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_payment);

View File

@@ -69,6 +69,10 @@ dictionary ReceivePaymentResponse {
string invoice;
};
dictionary BackupRequest {
string? backup_path = null;
};
dictionary RestoreRequest {
string? backup_path = null;
};
@@ -145,7 +149,7 @@ interface BindingLiquidSdk {
void sync();
[Throws=LiquidSdkError]
void backup();
void backup(BackupRequest req);
[Throws=LiquidSdkError]
void restore(RestoreRequest req);

View File

@@ -75,8 +75,8 @@ impl BindingLiquidSdk {
self.sdk.empty_wallet_cache().map_err(Into::into)
}
pub fn backup(&self) -> LiquidSdkResult<()> {
self.sdk.backup().map_err(Into::into)
pub fn backup(&self, req: BackupRequest) -> LiquidSdkResult<()> {
self.sdk.backup(req).map_err(Into::into)
}
pub fn restore(&self, req: RestoreRequest) -> LiquidSdkResult<()> {

View File

@@ -86,8 +86,8 @@ impl BindingLiquidSdk {
self.sdk.empty_wallet_cache().map_err(Into::into)
}
pub fn backup(&self) -> Result<(), LiquidSdkError> {
self.sdk.backup().map_err(Into::into)
pub fn backup(&self, req: BackupRequest) -> Result<(), LiquidSdkError> {
self.sdk.backup(req).map_err(Into::into)
}
pub fn restore(&self, req: RestoreRequest) -> Result<(), LiquidSdkError> {

View File

@@ -60,6 +60,21 @@ impl CstDecode<String> for *mut wire_cst_list_prim_u_8_strict {
String::from_utf8(vec).unwrap()
}
}
impl CstDecode<crate::model::BackupRequest> for wire_cst_backup_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::BackupRequest {
crate::model::BackupRequest {
backup_path: self.backup_path.cst_decode(),
}
}
}
impl CstDecode<crate::model::BackupRequest> for *mut wire_cst_backup_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::BackupRequest {
let wrap = unsafe { flutter_rust_bridge::for_generated::box_from_leak_ptr(self) };
CstDecode::<crate::model::BackupRequest>::cst_decode(*wrap).into()
}
}
impl CstDecode<crate::model::ConnectRequest> for *mut wire_cst_connect_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::ConnectRequest {
@@ -350,6 +365,18 @@ impl CstDecode<crate::model::SendPaymentResponse> for wire_cst_send_payment_resp
}
}
}
impl NewWithNullPtr for wire_cst_backup_request {
fn new_with_null_ptr() -> Self {
Self {
backup_path: core::ptr::null_mut(),
}
}
}
impl Default for wire_cst_backup_request {
fn default() -> Self {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_connect_request {
fn new_with_null_ptr() -> Self {
Self {
@@ -550,8 +577,9 @@ pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_ad
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup(
port_: i64,
that: usize,
req: *mut wire_cst_backup_request,
) {
wire__crate__bindings__BindingLiquidSdk_backup_impl(port_, that)
wire__crate__bindings__BindingLiquidSdk_backup_impl(port_, that, req)
}
#[no_mangle]
@@ -658,6 +686,14 @@ pub extern "C" fn frbgen_breez_liquid_rust_arc_decrement_strong_count_RustOpaque
}
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_backup_request(
) -> *mut wire_cst_backup_request {
flutter_rust_bridge::for_generated::new_leak_box_ptr(
wire_cst_backup_request::new_with_null_ptr(),
)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_connect_request(
) -> *mut wire_cst_connect_request {
@@ -747,6 +783,11 @@ pub extern "C" fn frbgen_breez_liquid_cst_new_list_prim_u_8_strict(
flutter_rust_bridge::for_generated::new_leak_box_ptr(ans)
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_backup_request {
backup_path: *mut wire_cst_list_prim_u_8_strict,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_connect_request {

View File

@@ -86,6 +86,7 @@ fn wire__crate__bindings__BindingLiquidSdk_backup_impl(
that: impl CstDecode<
RustOpaqueNom<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BindingLiquidSdk>>,
>,
req: impl CstDecode<crate::model::BackupRequest>,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::DcoCodec, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
@@ -95,6 +96,7 @@ fn wire__crate__bindings__BindingLiquidSdk_backup_impl(
},
move || {
let api_that = that.cst_decode();
let api_req = req.cst_decode();
move |context| {
transform_result_dco((move || {
let mut api_that_decoded = None;
@@ -111,7 +113,7 @@ fn wire__crate__bindings__BindingLiquidSdk_backup_impl(
}
}
let api_that = api_that_decoded.unwrap();
crate::bindings::BindingLiquidSdk::backup(&api_that)
crate::bindings::BindingLiquidSdk::backup(&api_that, api_req)
})())
}
},
@@ -578,6 +580,16 @@ impl SseDecode for String {
}
}
impl SseDecode for crate::model::BackupRequest {
// 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_backupPath = <Option<String>>::sse_decode(deserializer);
return crate::model::BackupRequest {
backup_path: var_backupPath,
};
}
}
impl SseDecode for bool {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -1016,6 +1028,20 @@ impl flutter_rust_bridge::IntoIntoDart<FrbWrapper<BindingLiquidSdk>> for Binding
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::BackupRequest {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[self.backup_path.into_into_dart().into_dart()].into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::model::BackupRequest {}
impl flutter_rust_bridge::IntoIntoDart<crate::model::BackupRequest>
for crate::model::BackupRequest
{
fn into_into_dart(self) -> crate::model::BackupRequest {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::ConnectRequest {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
@@ -1392,6 +1418,13 @@ impl SseEncode for String {
}
}
impl SseEncode for crate::model::BackupRequest {
// 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.backup_path, serializer);
}
}
impl SseEncode for bool {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {

View File

@@ -152,6 +152,15 @@ pub struct GetInfoResponse {
pub pubkey: String,
}
#[derive(Debug, Serialize)]
pub struct BackupRequest {
/// Path to the backup.
///
/// If not set, it defaults to `backup.sql` for mainnet and `backup-testnet.sql` for testnet.
/// The file will be saved in [ConnectRequest]'s `data_dir`.
pub backup_path: Option<String>,
}
#[derive(Debug, Serialize)]
pub struct RestoreRequest {
pub backup_path: Option<String>,

View File

@@ -6,27 +6,16 @@ use super::Persister;
use crate::model::Network;
impl Persister {
pub(crate) fn get_backup_path(&self) -> PathBuf {
pub(crate) fn get_default_backup_path(&self) -> PathBuf {
self.main_db_dir.join(match self.network {
Network::Liquid => "backup.sql",
Network::LiquidTestnet => "backup-testnet.sql",
})
}
pub(crate) fn backup(&self) -> Result<()> {
pub(crate) fn backup(&self, backup_path: PathBuf) -> Result<()> {
let con = self.get_connection()?;
let backup_file = match self.network {
Network::Liquid => "backup.sql",
Network::LiquidTestnet => "backup-testnet.sql",
};
con.backup(
rusqlite::DatabaseName::Main,
self.main_db_dir.join(backup_file),
None,
)?;
con.backup(rusqlite::DatabaseName::Main, backup_path, None)?;
Ok(())
}

View File

@@ -1234,14 +1234,6 @@ impl LiquidSdk {
Ok(())
}
pub fn restore(&self, req: RestoreRequest) -> Result<()> {
let backup_path = match req.backup_path {
Some(p) => PathBuf::from_str(&p)?,
None => self.persister.get_backup_path(),
};
self.persister.restore_from_backup(backup_path)
}
/// Synchronize the DB with mempool and onchain data
pub async fn sync(&self) -> Result<()> {
let t0 = Instant::now();
@@ -1253,8 +1245,20 @@ impl LiquidSdk {
Ok(())
}
pub fn backup(&self) -> Result<()> {
self.persister.backup()
pub fn backup(&self, req: BackupRequest) -> Result<()> {
let backup_path = req
.backup_path
.map(PathBuf::from)
.unwrap_or(self.persister.get_default_backup_path());
self.persister.backup(backup_path)
}
pub fn restore(&self, req: RestoreRequest) -> Result<()> {
let backup_path = req
.backup_path
.map(PathBuf::from)
.unwrap_or(self.persister.get_default_backup_path());
self.persister.restore_from_backup(backup_path)
}
fn get_liquid_swap_key(&self) -> Result<LiquidSwapKey, PaymentError> {

View File

@@ -30,8 +30,8 @@ class BindingLiquidSdk extends RustOpaque {
Stream<LiquidSdkEvent> addEventListener({dynamic hint}) =>
RustLib.instance.api.crateBindingsBindingLiquidSdkAddEventListener(that: this, hint: hint);
Future<void> backup({dynamic hint}) =>
RustLib.instance.api.crateBindingsBindingLiquidSdkBackup(that: this, hint: hint);
Future<void> backup({required BackupRequest req, dynamic hint}) =>
RustLib.instance.api.crateBindingsBindingLiquidSdkBackup(that: this, req: req, hint: hint);
Future<void> emptyWalletCache({dynamic hint}) =>
RustLib.instance.api.crateBindingsBindingLiquidSdkEmptyWalletCache(that: this, hint: hint);

View File

@@ -66,7 +66,8 @@ abstract class RustLibApi extends BaseApi {
Stream<LiquidSdkEvent> crateBindingsBindingLiquidSdkAddEventListener(
{required BindingLiquidSdk that, dynamic hint});
Future<void> crateBindingsBindingLiquidSdkBackup({required BindingLiquidSdk that, dynamic hint});
Future<void> crateBindingsBindingLiquidSdkBackup(
{required BindingLiquidSdk that, required BackupRequest req, dynamic hint});
Future<void> crateBindingsBindingLiquidSdkEmptyWalletCache({required BindingLiquidSdk that, dynamic hint});
@@ -140,20 +141,22 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
);
@override
Future<void> crateBindingsBindingLiquidSdkBackup({required BindingLiquidSdk that, dynamic hint}) {
Future<void> crateBindingsBindingLiquidSdkBackup(
{required BindingLiquidSdk that, required BackupRequest req, dynamic hint}) {
return handler.executeNormal(NormalTask(
callFfi: (port_) {
var arg0 =
cst_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
that);
return wire.wire__crate__bindings__BindingLiquidSdk_backup(port_, arg0);
var arg1 = cst_encode_box_autoadd_backup_request(req);
return wire.wire__crate__bindings__BindingLiquidSdk_backup(port_, arg0, arg1);
},
codec: DcoCodec(
decodeSuccessData: dco_decode_unit,
decodeErrorData: dco_decode_liquid_sdk_error,
),
constMeta: kCrateBindingsBindingLiquidSdkBackupConstMeta,
argValues: [that],
argValues: [that, req],
apiImpl: this,
hint: hint,
));
@@ -161,7 +164,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
TaskConstMeta get kCrateBindingsBindingLiquidSdkBackupConstMeta => const TaskConstMeta(
debugName: "BindingLiquidSdk_backup",
argNames: ["that"],
argNames: ["that", "req"],
);
@override
@@ -467,12 +470,28 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return raw as String;
}
@protected
BackupRequest dco_decode_backup_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 1) throw Exception('unexpected arr length: expect 1 but see ${arr.length}');
return BackupRequest(
backupPath: dco_decode_opt_String(arr[0]),
);
}
@protected
bool dco_decode_bool(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return raw as bool;
}
@protected
BackupRequest dco_decode_box_autoadd_backup_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return dco_decode_backup_request(raw);
}
@protected
ConnectRequest dco_decode_box_autoadd_connect_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -860,12 +879,25 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return utf8.decoder.convert(inner);
}
@protected
BackupRequest sse_decode_backup_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_backupPath = sse_decode_opt_String(deserializer);
return BackupRequest(backupPath: var_backupPath);
}
@protected
bool sse_decode_bool(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
return deserializer.buffer.getUint8() != 0;
}
@protected
BackupRequest sse_decode_box_autoadd_backup_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
return (sse_decode_backup_request(deserializer));
}
@protected
ConnectRequest sse_decode_box_autoadd_connect_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -1324,12 +1356,24 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_list_prim_u_8_strict(utf8.encoder.convert(self), serializer);
}
@protected
void sse_encode_backup_request(BackupRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_opt_String(self.backupPath, serializer);
}
@protected
void sse_encode_bool(bool self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
serializer.buffer.putUint8(self ? 1 : 0);
}
@protected
void sse_encode_box_autoadd_backup_request(BackupRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_backup_request(self, serializer);
}
@protected
void sse_encode_box_autoadd_connect_request(ConnectRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs

View File

@@ -43,9 +43,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
String dco_decode_String(dynamic raw);
@protected
BackupRequest dco_decode_backup_request(dynamic raw);
@protected
bool dco_decode_bool(dynamic raw);
@protected
BackupRequest dco_decode_box_autoadd_backup_request(dynamic raw);
@protected
ConnectRequest dco_decode_box_autoadd_connect_request(dynamic raw);
@@ -174,9 +180,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
String sse_decode_String(SseDeserializer deserializer);
@protected
BackupRequest sse_decode_backup_request(SseDeserializer deserializer);
@protected
bool sse_decode_bool(SseDeserializer deserializer);
@protected
BackupRequest sse_decode_box_autoadd_backup_request(SseDeserializer deserializer);
@protected
ConnectRequest sse_decode_box_autoadd_connect_request(SseDeserializer deserializer);
@@ -299,6 +311,14 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
return cst_encode_list_prim_u_8_strict(utf8.encoder.convert(raw));
}
@protected
ffi.Pointer<wire_cst_backup_request> cst_encode_box_autoadd_backup_request(BackupRequest raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
final ptr = wire.cst_new_box_autoadd_backup_request();
cst_api_fill_to_wire_backup_request(raw, ptr.ref);
return ptr;
}
@protected
ffi.Pointer<wire_cst_connect_request> cst_encode_box_autoadd_connect_request(ConnectRequest raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
@@ -409,6 +429,17 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
return raw.toInt();
}
@protected
void cst_api_fill_to_wire_backup_request(BackupRequest apiObj, wire_cst_backup_request wireObj) {
wireObj.backup_path = cst_encode_opt_String(apiObj.backupPath);
}
@protected
void cst_api_fill_to_wire_box_autoadd_backup_request(
BackupRequest apiObj, ffi.Pointer<wire_cst_backup_request> wireObj) {
cst_api_fill_to_wire_backup_request(apiObj, wireObj.ref);
}
@protected
void cst_api_fill_to_wire_box_autoadd_connect_request(
ConnectRequest apiObj, ffi.Pointer<wire_cst_connect_request> wireObj) {
@@ -712,9 +743,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_String(String self, SseSerializer serializer);
@protected
void sse_encode_backup_request(BackupRequest self, SseSerializer serializer);
@protected
void sse_encode_bool(bool self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_backup_request(BackupRequest self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_connect_request(ConnectRequest self, SseSerializer serializer);
@@ -882,18 +919,22 @@ class RustLibWire implements BaseWire {
void wire__crate__bindings__BindingLiquidSdk_backup(
int port_,
int that,
ffi.Pointer<wire_cst_backup_request> req,
) {
return _wire__crate__bindings__BindingLiquidSdk_backup(
port_,
that,
req,
);
}
late final _wire__crate__bindings__BindingLiquidSdk_backupPtr =
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int64, ffi.UintPtr)>>(
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup');
late final _wire__crate__bindings__BindingLiquidSdk_backupPtr = _lookup<
ffi
.NativeFunction<ffi.Void Function(ffi.Int64, ffi.UintPtr, ffi.Pointer<wire_cst_backup_request>)>>(
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup');
late final _wire__crate__bindings__BindingLiquidSdk_backup =
_wire__crate__bindings__BindingLiquidSdk_backupPtr.asFunction<void Function(int, int)>();
_wire__crate__bindings__BindingLiquidSdk_backupPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_backup_request>)>();
void wire__crate__bindings__BindingLiquidSdk_empty_wallet_cache(
int port_,
@@ -1111,6 +1152,16 @@ class RustLibWire implements BaseWire {
_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdkPtr
.asFunction<void Function(ffi.Pointer<ffi.Void>)>();
ffi.Pointer<wire_cst_backup_request> cst_new_box_autoadd_backup_request() {
return _cst_new_box_autoadd_backup_request();
}
late final _cst_new_box_autoadd_backup_requestPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_backup_request> Function()>>(
'frbgen_breez_liquid_cst_new_box_autoadd_backup_request');
late final _cst_new_box_autoadd_backup_request =
_cst_new_box_autoadd_backup_requestPtr.asFunction<ffi.Pointer<wire_cst_backup_request> Function()>();
ffi.Pointer<wire_cst_connect_request> cst_new_box_autoadd_connect_request() {
return _cst_new_box_autoadd_connect_request();
}
@@ -1257,6 +1308,10 @@ final class wire_cst_list_prim_u_8_strict extends ffi.Struct {
external int len;
}
final class wire_cst_backup_request extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> backup_path;
}
final class wire_cst_get_info_request extends ffi.Struct {
@ffi.Bool()
external bool with_scan;

View File

@@ -8,6 +8,26 @@ import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
import 'package:freezed_annotation/freezed_annotation.dart' hide protected;
part 'model.freezed.dart';
class BackupRequest {
/// Path to the backup.
///
/// If not set, it defaults to `backup.sql` for mainnet and `backup-testnet.sql` for testnet.
/// The file will be saved in [ConnectRequest]'s `data_dir`.
final String? backupPath;
const BackupRequest({
this.backupPath,
});
@override
int get hashCode => backupPath.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is BackupRequest && runtimeType == other.runtimeType && backupPath == other.backupPath;
}
class ConnectRequest {
final String mnemonic;
final String? dataDir;

View File

@@ -60,19 +60,22 @@ class FlutterBreezLiquidBindings {
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup(
int port_,
int that,
ffi.Pointer<wire_cst_backup_request> req,
) {
return _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup(
port_,
that,
req,
);
}
late final _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backupPtr =
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int64, ffi.UintPtr)>>(
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup');
late final _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backupPtr = _lookup<
ffi
.NativeFunction<ffi.Void Function(ffi.Int64, ffi.UintPtr, ffi.Pointer<wire_cst_backup_request>)>>(
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup');
late final _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backup =
_frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_backupPtr
.asFunction<void Function(int, int)>();
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_backup_request>)>();
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_empty_wallet_cache(
int port_,
@@ -295,6 +298,17 @@ class FlutterBreezLiquidBindings {
_frbgen_breez_liquid_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdkPtr
.asFunction<void Function(ffi.Pointer<ffi.Void>)>();
ffi.Pointer<wire_cst_backup_request> frbgen_breez_liquid_cst_new_box_autoadd_backup_request() {
return _frbgen_breez_liquid_cst_new_box_autoadd_backup_request();
}
late final _frbgen_breez_liquid_cst_new_box_autoadd_backup_requestPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_backup_request> Function()>>(
'frbgen_breez_liquid_cst_new_box_autoadd_backup_request');
late final _frbgen_breez_liquid_cst_new_box_autoadd_backup_request =
_frbgen_breez_liquid_cst_new_box_autoadd_backup_requestPtr
.asFunction<ffi.Pointer<wire_cst_backup_request> Function()>();
ffi.Pointer<wire_cst_connect_request> frbgen_breez_liquid_cst_new_box_autoadd_connect_request() {
return _frbgen_breez_liquid_cst_new_box_autoadd_connect_request();
}
@@ -464,6 +478,10 @@ final class wire_cst_list_prim_u_8_strict extends ffi.Struct {
external int len;
}
final class wire_cst_backup_request extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> backup_path;
}
final class wire_cst_get_info_request extends ffi.Struct {
@ffi.Bool()
external bool with_scan;

View File

@@ -3,6 +3,37 @@ import breez_liquid_sdk.*
import com.facebook.react.bridge.*
import java.util.*
fun asBackupRequest(backupRequest: ReadableMap): BackupRequest? {
if (!validateMandatoryFields(
backupRequest,
arrayOf(),
)
) {
return null
}
val backupPath = if (hasNonNullKey(backupRequest, "backupPath")) backupRequest.getString("backupPath") else null
return BackupRequest(
backupPath,
)
}
fun readableMapOf(backupRequest: BackupRequest): ReadableMap {
return readableMapOf(
"backupPath" to backupRequest.backupPath,
)
}
fun asBackupRequestList(arr: ReadableArray): List<BackupRequest> {
val list = ArrayList<BackupRequest>()
for (value in arr.toArrayList()) {
when (value) {
is ReadableMap -> list.add(asBackupRequest(value)!!)
else -> throw LiquidSdkException.Generic(errUnexpectedType("${value::class.java.name}"))
}
}
return list
}
fun asConnectRequest(connectRequest: ReadableMap): ConnectRequest? {
if (!validateMandatoryFields(
connectRequest,

View File

@@ -218,10 +218,17 @@ class BreezLiquidSDKModule(reactContext: ReactApplicationContext) : ReactContext
}
@ReactMethod
fun backup(promise: Promise) {
fun backup(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
getBindingLiquidSdk().backup()
val backupRequest =
asBackupRequest(
req,
) ?: run { throw LiquidSdkException.Generic(errMissingMandatoryField("req", "BackupRequest")) }
getBindingLiquidSdk().backup(backupRequest)
promise.resolve(readableMapOf("status" to "ok"))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)

View File

@@ -2,6 +2,42 @@ import BreezLiquidSDK
import Foundation
enum BreezLiquidSDKMapper {
static func asBackupRequest(backupRequest: [String: Any?]) throws -> BackupRequest {
var backupPath: String?
if hasNonNilKey(data: backupRequest, key: "backupPath") {
guard let backupPathTmp = backupRequest["backupPath"] as? String else {
throw LiquidSdkError.Generic(message: errUnexpectedValue(fieldName: "backupPath"))
}
backupPath = backupPathTmp
}
return BackupRequest(
backupPath: backupPath)
}
static func dictionaryOf(backupRequest: BackupRequest) -> [String: Any?] {
return [
"backupPath": backupRequest.backupPath == nil ? nil : backupRequest.backupPath,
]
}
static func asBackupRequestList(arr: [Any]) throws -> [BackupRequest] {
var list = [BackupRequest]()
for value in arr {
if let val = value as? [String: Any?] {
var backupRequest = try asBackupRequest(backupRequest: val)
list.append(backupRequest)
} else {
throw LiquidSdkError.Generic(message: errUnexpectedType(typeName: "BackupRequest"))
}
}
return list
}
static func arrayOf(backupRequestList: [BackupRequest]) -> [Any] {
return backupRequestList.map { v -> [String: Any?] in dictionaryOf(backupRequest: v) }
}
static func asConnectRequest(connectRequest: [String: Any?]) throws -> ConnectRequest {
guard let mnemonic = connectRequest["mnemonic"] as? String else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "mnemonic", typeName: "ConnectRequest"))

View File

@@ -61,7 +61,8 @@ RCT_EXTERN_METHOD(
)
RCT_EXTERN_METHOD(
backup: (RCTPromiseResolveBlock)resolve
backup: (NSDictionary*)req
resolve: (RCTPromiseResolveBlock)resolve
reject: (RCTPromiseRejectBlock)reject
)

View File

@@ -171,10 +171,11 @@ class RNBreezLiquidSDK: RCTEventEmitter {
}
}
@objc(backup:reject:)
func backup(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
@objc(backup:resolve:reject:)
func backup(_ req: [String: Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
do {
try getBindingLiquidSdk().backup()
let backupRequest = try BreezLiquidSDKMapper.asBackupRequest(backupRequest: req)
try getBindingLiquidSdk().backup(req: backupRequest)
resolve(["status": "ok"])
} catch let err {
rejectErr(err: err, reject: reject)

View File

@@ -19,6 +19,10 @@ const BreezLiquidSDK = NativeModules.RNBreezLiquidSDK
const BreezLiquidSDKEmitter = new NativeEventEmitter(BreezLiquidSDK)
export interface BackupRequest {
backupPath?: string
}
export interface ConnectRequest {
mnemonic: string
network: Network
@@ -179,8 +183,8 @@ export const sync = async (): Promise<void> => {
await BreezLiquidSDK.sync()
}
export const backup = async (): Promise<void> => {
await BreezLiquidSDK.backup()
export const backup = async (req: BackupRequest): Promise<void> => {
await BreezLiquidSDK.backup(req)
}
export const restore = async (req: RestoreRequest): Promise<void> => {