Skip to content

Commit

Permalink
Add the ability to import/export channel.db
Browse files Browse the repository at this point in the history
  • Loading branch information
hsjoberg committed May 2, 2024
1 parent 10d57bb commit 1ce277b
Show file tree
Hide file tree
Showing 12 changed files with 536 additions and 94 deletions.
50 changes: 50 additions & 0 deletions android/app/src/main/java/com/blixtwallet/LndMobileTools.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.Manifest;
import android.app.ActivityManager;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.FileObserver;
import android.os.Process;
import android.util.Base64;
Expand Down Expand Up @@ -756,6 +757,55 @@ public void getInternalFiles(Promise promise) {
}
}

@ReactMethod
public void saveChannelDbFile(Promise promise) {
// This promise will be resolved in MainActivity
MainActivity.tmpExportChannelDbPromise = promise;
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("application/octet-stream");
intent.putExtra(Intent.EXTRA_TITLE, "channel.db");
getReactApplicationContext().getCurrentActivity().startActivityForResult(intent, MainActivity.INTENT_EXPORTCHANNELDBFILE);
}

@ReactMethod
public void importChannelDbFile(String channelDbImportPath, Promise promise) {
Log.i(TAG, getReactApplicationContext().getFilesDir().toString() + "/data/graph/" + BuildConfig.CHAIN + "/channel.db");
try {
File sourceFile = new File(channelDbImportPath);

String channelDbFilePath = getReactApplicationContext().getFilesDir().toString() + "/data/graph/" + BuildConfig.CHAIN + "/channel.db";
File destChannelDbFile = new File(channelDbFilePath);

// Delete the channel.db file first if there is one
destChannelDbFile.delete();

File destFile = new File(channelDbFilePath);
if (!destFile.exists() && !destFile.createNewFile()) {
promise.reject(new IOException("Failed to create destination channel.db file"));
return;
}

// Copy content
InputStream in = new FileInputStream(sourceFile);
OutputStream out = new FileOutputStream(destFile);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
out.flush();
out.close();

// sourceFile.delete(); // Delete the cached file

promise.resolve(true);
} catch (IOException error) {
promise.reject(error);
}
}

private void checkWriteExternalStoragePermission(@NonNull RequestWriteExternalStoragePermissionCallback successCallback,
@NonNull Runnable failCallback,
@NonNull Runnable failPermissionCheckcallback) {
Expand Down
34 changes: 32 additions & 2 deletions android/app/src/main/java/com/blixtwallet/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.os.Bundle
import android.widget.Toast
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.bridge.Promise
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
import dev.doubledot.doki.ui.DokiActivity
Expand Down Expand Up @@ -92,6 +93,30 @@ class MainActivity : ReactActivity() {
} catch (e: IOException) {
Toast.makeText(this, "Error " + e.message, Toast.LENGTH_LONG).show()
}
} else if (requestCode == INTENT_EXPORTCHANNELDBFILE && resultCode == RESULT_OK) {
val destUri = data!!.data
val sourceLocation = File(filesDir.toString() + "/data/graph/" + BuildConfig.CHAIN + "/channel.db")
try {
val `in`: InputStream = FileInputStream(sourceLocation)
val out = contentResolver.openOutputStream(destUri!!)
val buf = ByteArray(1024)
var len: Int
while (`in`.read(buf).also { len = it } > 0) {
out!!.write(buf, 0, len)
}
`in`.close()
out!!.close()

if (tmpExportChannelDbPromise != null) {
Toast.makeText(this, "promise is not null", Toast.LENGTH_LONG).show()
tmpExportChannelDbPromise!!.resolve(true)
} else {
Toast.makeText(this, "promise is null", Toast.LENGTH_LONG).show()
}
} catch (e: IOException) {
Toast.makeText(this, "Error " + e.message, Toast.LENGTH_LONG).show()
tmpExportChannelDbPromise!!.reject(e)
}
}
}

Expand All @@ -111,14 +136,19 @@ class MainActivity : ReactActivity() {
@JvmField
var INTENT_EXPORTCHANBACKUP = 101
@JvmField
var tmpChanBackup: ByteArray = ByteArray(0)
@JvmField
var INTENT_EXPORTCHANBACKUPFILE = 102
@JvmField
var INTENT_COPYSPEEDLOADERLOG = 103
@JvmField
var tmpChanBackup: ByteArray = ByteArray(0)
var INTENT_EXPORTCHANNELDBFILE = 104
@JvmField
var tmpExportChannelDbPromise: Promise? = null
@JvmField
var currentActivity: WeakReference<MainActivity>? = null
@JvmStatic
val activity: MainActivity?
get() = currentActivity!!.get()
}
}
}
1 change: 1 addition & 0 deletions ios/LndMobile/Lnd.swift
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ open class Lnd {
"VerifyMessage": { bytes, cb in LndmobileVerifyMessage(bytes, cb) },
"SignMessage": { bytes, cb in LndmobileSignMessage(bytes, cb) },
"SignerSignMessage": { bytes, cb in LndmobileSignerSignMessage(bytes, cb) },
"RestoreChannelBackups": { bytes, cb in LndmobileRestoreChannelBackups(bytes, cb) },

// autopilot
"AutopilotStatus": { bytes, cb in LndmobileAutopilotStatus(bytes, cb) },
Expand Down
23 changes: 20 additions & 3 deletions src/Main.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from "react";
import { StatusBar, Alert, NativeModules } from "react-native";
import { Spinner, H1, H2 } from "native-base";
import { Spinner, H1, H2, Text } from "native-base";
import {
createStackNavigator,
CardStyleInterpolators,
Expand Down Expand Up @@ -40,6 +40,7 @@ import useStackNavigationOptions from "./hooks/useStackNavigationOptions";
import { navigator } from "./utils/navigation";
import { PLATFORM } from "./utils/constants";
import Prompt, { IPromptNavigationProps } from "./windows/HelperWindows/Prompt";
import { isInstanceBricked } from "./storage/app";

const RootStack = createStackNavigator();

Expand Down Expand Up @@ -86,6 +87,7 @@ export default function Main() {
const appReady = useStoreState((store) => store.appReady);
const lightningReady = useStoreState((store) => store.lightning.ready);
const walletCreated = useStoreState((store) => store.walletCreated);
const importChannelDbOnStartup = useStoreState((store) => store.importChannelDbOnStartup);
const loggedIn = useStoreState((store) => store.security.loggedIn);
const initializeApp = useStoreActions((store) => store.initializeApp);
const [initialRoute, setInitialRoute] = useState("Loading");
Expand All @@ -95,13 +97,22 @@ export default function Main() {
(store) => store.settings.screenTransitionsEnabled,
);

const [state, setState] = useState<"init" | "authentication" | "onboarding" | "started">("init");
console.log("walletCreated", walletCreated);

const [state, setState] = useState<
"init" | "authentication" | "onboarding" | "started" | "bricked"
>("init");

useEffect(() => {
// tslint:disable-next-line
(async () => {
if (!appReady) {
try {
if (await isInstanceBricked()) {
setState("bricked");
return;
}

await initializeApp();
} catch (e) {
toast(e.message, 0, "danger");
Expand All @@ -111,6 +122,8 @@ export default function Main() {
}, [appReady]);

useEffect(() => {
console.log("useEffect", lightningReady, walletCreated, state);

if (!appReady) {
return;
}
Expand All @@ -120,7 +133,7 @@ export default function Main() {
setState("authentication");
} else if (!lightningReady) {
setState("started");
if (!walletCreated) {
if (!walletCreated && !importChannelDbOnStartup) {
setInitialRoute("Welcome");
} else {
// try {
Expand Down Expand Up @@ -225,6 +238,10 @@ export default function Main() {
return <Authentication />;
}

if (state === "bricked") {
return <Text>Bricked</Text>;
}

return (
<RootStack.Navigator initialRouteName={initialRoute} screenOptions={screenOptions}>
<RootStack.Screen
Expand Down
2 changes: 2 additions & 0 deletions src/lndmobile/LndMobile.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ export interface ILndMobileTools {
DEBUG_deleteSpeedloaderDgraphDirectory(): null;
DEBUG_deleteNeutrinoFiles(): boolean;
getInternalFiles(): Promise<Record<string, number>>;
saveChannelDbFile(): Promise<boolean>;
importChannelDbFile(channelDbPath: string): Promise<boolean>;

// Android-specific
getIntentStringData(): Promise<string | null>;
Expand Down
Loading

0 comments on commit 1ce277b

Please sign in to comment.