UNPKG

@ledgerhq/live-common

Version:
104 lines 4.98 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 = installLanguage; const errors_1 = require("@ledgerhq/errors"); const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const network_1 = __importDefault(require("@ledgerhq/live-network/network")); const errors_2 = require("../errors"); const api_1 = __importDefault(require("../manager/api")); const attemptToQuitApp_1 = __importDefault(require("./attemptToQuitApp")); const deviceAccess_1 = require("./deviceAccess"); const getAppAndVersion_1 = __importDefault(require("./getAppAndVersion")); const getDeviceInfo_1 = __importDefault(require("./getDeviceInfo")); const isDashboardName_1 = require("./isDashboardName"); function installLanguage({ deviceId, deviceName, request, }) { const { language } = request; const sub = (0, deviceAccess_1.withDevice)(deviceId, deviceName ? { matchDeviceByName: deviceName } : undefined)(transport => new rxjs_1.Observable(subscriber => { const timeoutSub = (0, rxjs_1.of)({ type: "unresponsiveDevice", }) .pipe((0, operators_1.delay)(1000)) .subscribe(e => subscriber.next(e)); const sub = (0, rxjs_1.from)((0, getDeviceInfo_1.default)(transport)) .pipe((0, operators_1.mergeMap)(async (deviceInfo) => { timeoutSub.unsubscribe(); if (language === "english") { await uninstallAllLanguages(transport); subscriber.next({ type: "languageInstalled", }); subscriber.complete(); return; } const languages = await api_1.default.getLanguagePackagesForDevice(deviceInfo); const packs = languages.filter((l) => l.language === language); if (!packs.length) return subscriber.error(new errors_1.LanguageNotFound(language)); const pack = packs[0]; const { apdu_install_url } = pack; const url = apdu_install_url; const { data: rawApdus } = await (0, network_1.default)({ method: "GET", url, }); const apdus = rawApdus.split(/\r?\n/).filter(Boolean); await uninstallAllLanguages(transport); for (let i = 0; i < apdus.length; i++) { if (apdus[i].startsWith("e030")) { subscriber.next({ type: "devicePermissionRequested", }); } const response = await transport.exchange(Buffer.from(apdus[i], "hex")); const status = response.readUInt16BE(response.length - 2); const statusStr = status.toString(16); // Some error handling if (status === errors_1.StatusCodes.USER_REFUSED_ON_DEVICE) { return subscriber.error(new errors_2.LanguageInstallRefusedOnDevice(statusStr)); } else if (status === errors_1.StatusCodes.NOT_ENOUGH_SPACE) { return subscriber.error(new errors_1.ManagerNotEnoughSpaceError()); } else if (status !== errors_1.StatusCodes.OK) { return subscriber.error(new errors_1.TransportError("Unexpected device response", statusStr)); } subscriber.next({ type: "progress", progress: (i + 1) / apdus.length, }); } subscriber.next({ type: "languageInstalled", }); subscriber.complete(); }), (0, operators_1.catchError)((e) => { if (e instanceof errors_1.DeviceOnDashboardExpected || (e && e instanceof errors_1.TransportStatusError && [0x6e00, 0x6d00, 0x6e01, 0x6d01, 0x6d02].includes(e.statusCode))) { return (0, rxjs_1.from)((0, getAppAndVersion_1.default)(transport)).pipe((0, operators_1.concatMap)(appAndVersion => { return !(0, isDashboardName_1.isDashboardName)(appAndVersion.name) ? (0, attemptToQuitApp_1.default)(transport, appAndVersion) : (0, rxjs_1.of)({ type: "appDetected", }); })); } return (0, rxjs_1.throwError)(() => e); })) .subscribe(subscriber); return () => { timeoutSub.unsubscribe(); sub.unsubscribe(); }; })); return sub; } const uninstallAllLanguages = async (transport) => { await transport.send(0xe0, 0x33, 0xff, 0x00, undefined, [0x9000, 0x5501]); }; //# sourceMappingURL=installLanguage.js.map