Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: list files backed up #175

Merged
merged 3 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions backup-server/src/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,17 @@ class Storage {
//TODO must be a better way instead of iterating over all files
let files = [];
const list = await this.storage.listFiles();

list.forEach((file) => {
const [fileName] = file;
if (fileName.startsWith(filePath) && fileName.endsWith('.bin')) {
files.push(fileName.substring(fileName.lastIndexOf('/') + 1));
const [fullFilePath] = file;

if (fullFilePath.startsWith(filePath) && fullFilePath.endsWith('.bin')) {
//Ignore directories
if (fullFilePath.replaceAll(filePath, '').replace(/^\//, "").indexOf('/') !== -1) {
return;
}

files.push(fullFilePath.substring(fullFilePath.lastIndexOf('/') + 1));
}
});

Expand Down
24 changes: 23 additions & 1 deletion lib/android/src/main/java/com/reactnativeldk/LdkModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,6 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
promise.resolve((res as Result_TransactionNoneZ.Result_TransactionNoneZ_OK).res.hexEncodedString())
}


@ReactMethod
fun nodeSign(message: String, promise: Promise) {
keysManager ?: return handleReject(promise, LdkErrors.init_keys_manager)
Expand Down Expand Up @@ -1210,6 +1209,29 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
handleReject(promise, LdkErrors.backup_check_failed, Error(e))
}
}

@ReactMethod
fun backupListFiles(promise: Promise) {
if (BackupClient.requiresSetup) {
return handleReject(promise, LdkErrors.backup_setup_required)
}

try {
val list = BackupClient.listFiles()

val map = Arguments.createMap()
val files = Arguments.createArray()
list.first.forEach { files.pushString(it) }
val channelMonitors = Arguments.createArray()
list.second.forEach { channelMonitors.pushString(it) }
map.putArray("list", files)
map.putArray("channel_monitors", channelMonitors)

promise.resolve(map)
} catch (e: Exception) {
handleReject(promise, LdkErrors.backup_check_failed, Error(e))
}
}
}

object LdkEventEmitter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ class BackupClient {
}

@Throws(BackupError::class)
fun retrieveCompleteBackup(): CompleteBackup {
fun listFiles(): Pair<Array<String>, Array<String>> {
val bearer = authToken()

val url = backupUrl(Method.LIST)
Expand Down Expand Up @@ -310,20 +310,35 @@ class BackupClient {
inputStream.close()

val jsonObject = JSONObject(jsonString)
val fileList = jsonObject.getJSONArray("list")
val channelFileList = jsonObject.getJSONArray("channel_monitors")

println("fileList: $fileList")

return Pair(
Array(fileList.length()) { idx ->
fileList.getString(idx)
},
Array(channelFileList.length()) { idx ->
channelFileList.getString(idx)
},
)
}

@Throws(BackupError::class)
fun retrieveCompleteBackup(): CompleteBackup {
val list = listFiles()
val fileNames = list.first
val channelFileNames = list.second

val files = mutableMapOf<String, ByteArray>()
val fileNames = jsonObject.getJSONArray("list")
for (i in 0 until fileNames.length()) {
val filename = fileNames.getString(i)
files[filename] = retrieve(Label.MISC(filename))
for (fileName in fileNames) {
files[fileName] = retrieve(Label.MISC(fileName))
}

val channelFiles = mutableMapOf<String, ByteArray>()
val channelFileNames = jsonObject.getJSONArray("channel_monitors")
for (i in 0 until channelFileNames.length()) {
val filename = channelFileNames.getString(i)

channelFiles[filename] = retrieve(Label.CHANNEL_MONITOR(channelId=filename.replace(".bin", "")))
for (fileName in channelFileNames) {
channelFiles[fileName] = retrieve(Label.CHANNEL_MONITOR(channelId=fileName.replace(".bin", "")))
}

return CompleteBackup(files = files, channelFiles = channelFiles)
Expand Down
22 changes: 16 additions & 6 deletions lib/ios/Classes/BackupClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ struct BackupRetrieveBearer: Codable {
let expires: Int
}

struct ListFilesResponse: Codable {
let list: [String]
let channel_monitors: [String]
}

class BackupClient {
enum Label {
case ping
Expand Down Expand Up @@ -309,13 +314,8 @@ class BackupClient {
return try decrypt(encryptedBackup)
}

static func retrieveCompleteBackup() throws -> CompleteBackup {
static func listFiles() throws -> ListFilesResponse {
let bearer = try authToken()

struct ListFilesResponse: Codable {
let list: [String]
let channel_monitors: [String]
}

var backedUpFilenames: ListFilesResponse?

Expand Down Expand Up @@ -362,6 +362,11 @@ class BackupClient {
throw BackupError.missingResponse
}

return backedUpFilenames
}

static func retrieveCompleteBackup() throws -> CompleteBackup {
let backedUpFilenames = try listFiles()

var allFiles: [String: Data] = [:]
var channelFiles: [String: Data] = [:]
Expand All @@ -385,6 +390,11 @@ class BackupClient {
return CompleteBackup(files: allFiles, channelFiles: channelFiles)
}

struct BackupExists {
let exists: Bool
let channelFiles: Int
}

static func selfCheck() throws {
//Store a random encrypted string and retrieve it again to confirm the server is working
let ping = "ping\(arc4random_uniform(99999))"
Expand Down
2 changes: 2 additions & 0 deletions lib/ios/Ldk.m
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ @interface RCT_EXTERN_MODULE(Ldk, NSObject)
reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(backupSelfCheck:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(backupListFiles:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject)

@end

Expand Down
20 changes: 19 additions & 1 deletion lib/ios/Ldk.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ enum LdkErrors: String {
case backup_check_failed = "backup_check_failed"
case backup_restore_failed = "backup_restore_failed"
case backup_restore_failed_existing_files = "backup_restore_failed_existing_files"
case backup_list_files_failed = "backup_list_files_failed"
}

enum LdkCallbackResponses: String {
Expand Down Expand Up @@ -884,7 +885,7 @@ class Ldk: NSObject {
guard let invoice = res.getValue() else {
return handleReject(reject, .invoice_create_failed)
}

return resolve(invoice.asJson) //Invoice class extended in Helpers file
}

Expand Down Expand Up @@ -1323,6 +1324,23 @@ class Ldk: NSObject {
handleReject(reject, .backup_check_failed, error, error.localizedDescription)
}
}

@objc
func backupListFiles(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
guard !BackupClient.requiresSetup else {
return handleReject(reject, .backup_setup_required)
}

do {
let result = try BackupClient.listFiles()
resolve([
"list": result.list,
"channel_monitors": result.channel_monitors
])
} catch {
handleReject(reject, .backup_list_files_failed, error, error.localizedDescription)
}
}
}

//MARK: Singleton react native event emitter
Expand Down
2 changes: 1 addition & 1 deletion lib/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@synonymdev/react-native-ldk",
"title": "React Native LDK",
"version": "0.0.111",
"version": "0.0.112",
"description": "React Native wrapper for LDK",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down
13 changes: 13 additions & 0 deletions lib/src/ldk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
TAcceptChannelReq,
TBackupServerDetails,
TNodeSignReq,
TBackedUpFileList,
} from './utils/types';
import { extractPaymentRequest } from './utils/helpers';

Expand Down Expand Up @@ -1248,6 +1249,18 @@ class LDK {
return err(e);
}
}

/**
* List all files that have been backed up
*/
async backupListFiles(): Promise<Result<TBackedUpFileList>> {
try {
const res = await NativeLDK.backupListFiles();
return ok(res);
} catch (e) {
return err(e);
}
}
}

export default new LDK();
5 changes: 5 additions & 0 deletions lib/src/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,11 @@ export type TBackupServerDetails = {
serverPubKey: string;
};

export type TBackedUpFileList = {
list: [string];
channel_monitors: [string];
};

export type TNodeSignReq = {
message: string;
messagePrefix?: string;
Expand Down
Loading