UNPKG

@ledgerhq/live-common

Version:
72 lines 3.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.restoreAppData = void 0; const device_core_1 = require("@ledgerhq/device-core"); const rxjs_1 = require("rxjs"); const types_1 = require("./types"); /** * Restores the application data for a specific app on a Ledger device. * * @param transport - The transport object used to communicate with the Ledger device. * @param appName - The name of the application to restore. * @param appData - The data to restore. * @returns An observable that emits RestoreAppDataEvent according to the restore process. */ function restoreAppData(transport, appName, appData) { const obs = new rxjs_1.Observable(subscriber => { const chunkData = Buffer.from(appData, "base64"); const backupSize = chunkData.length; const sub = (0, rxjs_1.from)((0, device_core_1.restoreAppStorageInit)(transport, appName, backupSize)) .pipe((0, rxjs_1.switchMap)(async () => { // Initialize the restore process subscriber.next({ type: types_1.RestoreAppDataEventType.AppDataInitialized }); // Restore app data by chunks const MAX_CHUNK_SIZE = 255; let offset = 0; while (offset < backupSize) { subscriber.next({ type: types_1.RestoreAppDataEventType.Progress, data: Number((offset / backupSize).toFixed(2)), }); const chunkSize = Math.min(MAX_CHUNK_SIZE, backupSize - offset); const chunk = chunkData.subarray(offset, offset + chunkSize); await (0, device_core_1.restoreAppStorage)(transport, chunk); offset += chunkSize; } // Commit the restore process, last step await (0, device_core_1.restoreAppStorageCommit)(transport); subscriber.next({ type: types_1.RestoreAppDataEventType.AppDataRestored, }); subscriber.complete(); }), (0, rxjs_1.catchError)(e => { // No app data found on the app or the app does not support it if (e instanceof device_core_1.AppNotFound) { subscriber.next({ type: types_1.RestoreAppDataEventType.NoAppDataToRestore, }); subscriber.complete(); return (0, rxjs_1.of)(null); } // User refused on device if (e instanceof device_core_1.UserRefusedOnDevice) { // NOTE: Display a message to the user to retry the restore process // If he does not, we should delete the app data (in another flow) subscriber.next({ type: types_1.RestoreAppDataEventType.UserRefused, }); subscriber.complete(); return (0, rxjs_1.of)(null); } subscriber.complete(); throw e; })) .subscribe(); return () => { sub.unsubscribe(); }; }); return obs; } exports.restoreAppData = restoreAppData; //# sourceMappingURL=restoreAppData.js.map