UNPKG

@ledgerhq/live-common

Version:
90 lines 3.85 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = installApp; const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const errors_1 = require("@ledgerhq/errors"); const api_1 = __importDefault(require("../manager/api")); const polyfill_1 = require("../apps/polyfill"); const logs_1 = require("@ledgerhq/logs"); const _1 = require("."); const quitApp_1 = require("../deviceSDK/commands/quitApp"); const APP_INSTALL_RETRY_DELAY = 500; const APP_INSTALL_RETRY_LIMIT = 5; /** * Command to install a given app to a device. * * On error (except on locked device errors), a retry mechanism is set. * * @param transport * @param targetId Device firmware target id * @param app Info of the app to install * @param others Extended params: * - retryLimit: number of time this command is retried when any error occurs. Default to 5. * - retryDelayMs: delay in ms before retrying on an error. Default to 500ms. * @returns An Observable emitting installation progress * - progress: float number from 0 to 1 representing the installation progress */ function installApp(transport, targetId, app, { retryLimit = APP_INSTALL_RETRY_LIMIT, retryDelayMs = APP_INSTALL_RETRY_DELAY, } = {}) { const tracer = new logs_1.LocalTracer(_1.LOG_TYPE, { ...transport.getTraceContext(), function: "installApp", }); tracer.trace("Install app", { targetId, appName: app?.name, appVersion: app?.version, retryLimit, retryDelayMs, }); // Run quitApp just before ManagerAPI.install return (0, quitApp_1.quitApp)(transport).pipe((0, operators_1.switchMap)(() => api_1.default.install(transport, "install-app", { targetId, perso: app.perso, deleteKey: app.delete_key, firmware: app.firmware, firmwareKey: app.firmware_key, hash: app.hash, }).pipe((0, operators_1.retry)({ count: retryLimit, delay: (error, retryCount) => { // Not retrying on locked device errors if (error instanceof errors_1.LockedDeviceError || error instanceof errors_1.ManagerDeviceLockedError || error instanceof errors_1.UnresponsiveDeviceError) { tracer.trace(`Not retrying on error: ${error}`, { error, }); return (0, rxjs_1.throwError)(() => error); } tracer.trace(`Retrying (${retryCount}/${retryLimit}) on error: ${error}`, { error, retryLimit, retryDelayMs, }); return (0, rxjs_1.timer)(retryDelayMs); }, }), (0, operators_1.filter)((e) => e.type === "bulk-progress"), // only bulk progress interests the UI (0, operators_1.throttleTime)(100), // throttle to only emit 10 event/s max, to not spam the UI (0, operators_1.map)((e) => ({ progress: e.progress, })), // extract a stream of progress percentage (0, operators_1.catchError)((e) => { tracer.trace(`Error: ${e}`, { error: e }); if (!e || !e.message) return (0, rxjs_1.throwError)(() => e); const status = e.message.slice(e.message.length - 4); if (status === "6a83" || status === "6811") { const dependencies = (0, polyfill_1.getDependencies)(app.name); return (0, rxjs_1.throwError)(() => new errors_1.ManagerAppDepInstallRequired("", { appName: app.name, dependency: dependencies.join(", "), })); } return (0, rxjs_1.throwError)(() => e); })))); } //# sourceMappingURL=installApp.js.map