@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
66 lines (64 loc) • 2.57 kB
text/typescript
import { Observable, switchMap } from "rxjs";
import {
AppName,
AppStorageType,
BackupAppDataError,
BackupAppDataEvent,
BackupAppDataEventType,
StorageProvider,
} from "./types";
import { AppStorageInfo } from "@ledgerhq/device-core/index";
import { DeviceModelId } from "@ledgerhq/devices";
/**
* Backs up the application data for a specific app on a Ledger device. All interactions
* with the storage provider are handled by this function.
*
* @param storageProvider - The storage provider object used for storing the backup data.
* @param appName - The name of the application to backup.
* @param backupAppDataFn - The function that returns observable for the backup process.
* @returns An observable that emits BackupAppDataEvent during the backup process.
* @throws {BackupAppDataError}
*/
export function backupAppDataUseCase(
appName: AppName,
deviceModelId: DeviceModelId,
storageProvider: StorageProvider<AppStorageType>,
backupAppDataFn: () => Observable<BackupAppDataEvent>,
): Observable<BackupAppDataEvent> {
let appDataInfo: AppStorageInfo;
const obs: Observable<BackupAppDataEvent> = backupAppDataFn().pipe(
switchMap(async (event: BackupAppDataEvent): Promise<BackupAppDataEvent> => {
switch (event.type) {
case BackupAppDataEventType.AppDataInfoFetched: {
const appStorage = await storageProvider.getItem(`${deviceModelId}-${appName}`);
// Check if the app data is already backed up
if (appStorage && appStorage.appDataInfo?.hash === event.data.hash) {
/**
* We cannot get the observer's complete callback here, so need to execute it manually if needed
*/
return { type: BackupAppDataEventType.AppDataAlreadyBackedUp };
}
// If not, store the app data info and transfer the event
appDataInfo = event.data;
return event;
}
case BackupAppDataEventType.AppDataBackedUp:
// Store the app data
if (appDataInfo) {
await storageProvider.setItem(`${deviceModelId}-${appName}`, {
appDataInfo,
appData: event.data,
});
}
// Erase the app data, then return the event
return { type: BackupAppDataEventType.AppDataBackedUp, data: "" };
case BackupAppDataEventType.Progress:
case BackupAppDataEventType.NoAppDataToBackup:
return event;
default:
throw new BackupAppDataError("Invalid event type");
}
}),
);
return obs;
}