UNPKG

@ledgerhq/live-common

Version:
324 lines • 13.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-disable camelcase */ const errors_1 = require("@ledgerhq/errors"); const cache_1 = require("@ledgerhq/live-network/cache"); const network_1 = __importDefault(require("@ledgerhq/live-network/network")); const logs_1 = require("@ledgerhq/logs"); const invariant_1 = __importDefault(require("invariant")); const rxjs_1 = require("rxjs"); const operators_1 = require("rxjs/operators"); const semver_1 = __importDefault(require("semver")); const url_1 = __importDefault(require("url")); const package_json_1 = require("../../package.json"); const live_env_1 = require("@ledgerhq/live-env"); const socket_1 = require("../socket"); const socket_mock_1 = require("../socket/socket.mock"); const provider_1 = require("./provider"); const fetchMcusUseCase_1 = require("../device/use-cases/fetchMcusUseCase"); const remapSocketError = (context) => (0, operators_1.catchError)((e) => { if (!e || !e.message) return (0, rxjs_1.throwError)(() => e); if (e.message.startsWith("invalid literal")) { // hack to detect the case you're not in good condition (not in dashboard) return (0, rxjs_1.throwError)(() => new errors_1.DeviceOnDashboardExpected()); } const status = e instanceof errors_1.TransportStatusError ? e.statusCode.toString(16) : e.message.slice(e.message.length - 4); // TODO use StatusCode instead of this. switch (status) { case "6a80": case "6a81": case "6a8e": case "6a8f": return (0, rxjs_1.throwError)(() => new errors_1.ManagerAppAlreadyInstalledError()); case "6982": case "5303": return (0, rxjs_1.throwError)(() => new errors_1.ManagerDeviceLockedError()); case "6a84": case "5103": if (context === "firmware" || context === "mcu") { return (0, rxjs_1.throwError)(() => new errors_1.ManagerFirmwareNotEnoughSpaceError()); } return (0, rxjs_1.throwError)(() => new errors_1.ManagerNotEnoughSpaceError()); case "6a85": case "5102": if (context === "firmware" || context === "mcu") { return (0, rxjs_1.throwError)(() => new errors_1.UserRefusedFirmwareUpdate()); } return (0, rxjs_1.throwError)(() => new errors_1.ManagerNotEnoughSpaceError()); case "6985": case "5501": if (context === "firmware" || context === "mcu") { return (0, rxjs_1.throwError)(() => new errors_1.UserRefusedFirmwareUpdate()); } return (0, rxjs_1.throwError)(() => new errors_1.ManagerNotEnoughSpaceError()); default: return (0, rxjs_1.throwError)(() => e); } }); /** @deprecated use getAppsCatalogForDevice (from ledger-live-common/src/device/use-cases) instead */ const listApps = (0, cache_1.makeLRUCache)(async () => { const { data } = await (0, network_1.default)({ method: "GET", url: url_1.default.format({ pathname: `${(0, live_env_1.getEnv)("MANAGER_API_BASE")}/applications`, query: { livecommonversion: package_json_1.version, }, }), }); if (!data || !Array.isArray(data)) { throw new errors_1.NetworkDown(""); } return data; }, () => (0, live_env_1.getEnv)("MANAGER_API_BASE")); const listCategories = async () => { const r = await (0, network_1.default)({ method: "GET", url: url_1.default.format({ pathname: `${(0, live_env_1.getEnv)("MANAGER_API_BASE")}/categories`, query: { livecommonversion: package_json_1.version, }, }), }); return r.data; }; const compatibleMCUForDeviceInfo = (mcus, deviceInfo, provider) => mcus.filter(m => (deviceInfo.majMin === m.from_bootloader_version || deviceInfo.version === m.from_bootloader_version) && m.providers.includes(provider)); const findBestMCU = (compatibleMCU) => { let best = compatibleMCU[0]; for (let i = 1; i < compatibleMCU.length; i++) { if (semver_1.default.gt(semver_1.default.coerce(compatibleMCU[i].name) || "", semver_1.default.coerce(best.name) || "")) { best = compatibleMCU[i]; } } return best; }; const getLanguagePackagesForDevice = async (deviceInfo) => { const deviceVersion = await getDeviceVersion(deviceInfo.targetId, (0, provider_1.getProviderId)(deviceInfo)); const seFirmwareVersion = await getCurrentFirmware({ version: deviceInfo.version, deviceId: deviceVersion.id, provider: (0, provider_1.getProviderId)(deviceInfo), }); const { data } = await (0, network_1.default)({ method: "GET", url: url_1.default.format({ pathname: `${(0, live_env_1.getEnv)("MANAGER_API_BASE")}/language-package`, query: { livecommonversion: package_json_1.version, }, }), }); const allPackages = data.reduce((acc, response) => [ ...acc, ...response.language_package_version.map(p => ({ ...p, language: response.language, })), ], []); const packages = allPackages.filter(pack => pack.device_versions.includes(deviceVersion.id) && pack.se_firmware_final_versions.includes(seFirmwareVersion.id)); return packages; }; const getCurrentOSU = (0, cache_1.makeLRUCache)(async (input) => { const { data } = await (0, network_1.default)({ method: "GET", url: url_1.default.format({ pathname: `${(0, live_env_1.getEnv)("MANAGER_API_BASE")}/get_osu_version`, query: { livecommonversion: package_json_1.version, device_version: input.deviceId, version_name: `${input.version}-osu`, provider: input.provider, }, }), }); return data; }, a => `${(0, live_env_1.getEnv)("MANAGER_API_BASE")}_${a.version}_${a.deviceId}_${a.provider}`); const getCurrentFirmware = (0, cache_1.makeLRUCache)(async (input) => { const { data, } = await (0, network_1.default)({ method: "GET", url: url_1.default.format({ pathname: `${(0, live_env_1.getEnv)("MANAGER_API_BASE")}/get_firmware_version`, query: { livecommonversion: package_json_1.version, device_version: input.deviceId, version_name: input.version, provider: input.provider, }, }), }).catch(error => { const status = error?.status || error?.response?.status; if (status === 404) throw new errors_1.FirmwareNotRecognized(); throw error; }); return data; }, a => `${(0, live_env_1.getEnv)("MANAGER_API_BASE")}_${a.version}_${a.deviceId}_${a.provider}`); const getFinalFirmwareById = (0, cache_1.makeLRUCache)(async (id) => { const { data, } = await (0, network_1.default)({ method: "GET", url: url_1.default.format({ pathname: `${(0, live_env_1.getEnv)("MANAGER_API_BASE")}/firmware_final_versions/${id}`, query: { livecommonversion: package_json_1.version, }, }), }); return data; }, id => `${(0, live_env_1.getEnv)("MANAGER_API_BASE")}}_${String(id)}`); const getDeviceVersion = (0, cache_1.makeLRUCache)(async (targetId, provider) => { const { data, } = await (0, network_1.default)({ method: "GET", url: url_1.default.format({ pathname: `${(0, live_env_1.getEnv)("MANAGER_API_BASE")}/get_device_version`, query: { livecommonversion: package_json_1.version, provider, target_id: targetId, }, }), }).catch(error => { const status = error?.status || error?.response?.status; if (status === 404) throw new errors_1.FirmwareNotRecognized("manager api did not recognize targetId=" + targetId, { targetId, }); throw error; }); return data; }, (targetId, provider) => `${(0, live_env_1.getEnv)("MANAGER_API_BASE")}_${targetId}_${provider}`); const install = (transport, context, params, unresponsiveExpectedDuringBulk) => { if ((0, live_env_1.getEnv)("MOCK")) { return (0, socket_mock_1.createMockSocket)((0, socket_mock_1.secureChannelMock)(true), (0, socket_mock_1.bulkSocketMock)(3000)); } (0, logs_1.log)("manager", "install " + context, params); return (0, socket_1.createDeviceSocket)(transport, { url: url_1.default.format({ pathname: `${(0, live_env_1.getEnv)("BASE_SOCKET_URL")}/install`, query: { ...params, livecommonversion: package_json_1.version }, }), unresponsiveExpectedDuringBulk, }).pipe(remapSocketError(context)); }; const genuineCheck = (transport, { targetId, perso, }) => { if ((0, live_env_1.getEnv)("MOCK")) { return (0, socket_mock_1.createMockSocket)((0, socket_mock_1.secureChannelMock)(false), (0, socket_mock_1.resultMock)("0000")); } (0, logs_1.log)("manager", "genuineCheck", { targetId, perso, }); return (0, socket_1.createDeviceSocket)(transport, { url: url_1.default.format({ pathname: `${(0, live_env_1.getEnv)("BASE_SOCKET_URL")}/genuine`, query: { targetId, perso, livecommonversion: package_json_1.version, }, }), }).pipe((0, operators_1.map)(e => { if (e.type === "result") { return { type: "result", payload: String(e.payload || ""), }; } return e; })); }; const listInstalledApps = (transport, { targetId, perso, }) => { if ((0, live_env_1.getEnv)("MOCK")) { const result = global._listInstalledApps_mock_result; (0, invariant_1.default)(result, "using MOCK, global._listInstalledApps_mock_result must be set"); return (0, socket_mock_1.createMockSocket)((0, socket_mock_1.secureChannelMock)(false), (0, socket_mock_1.resultMock)(result)); } (0, logs_1.log)("manager", "listInstalledApps", { targetId, perso, }); return (0, socket_1.createDeviceSocket)(transport, { url: url_1.default.format({ pathname: `${(0, live_env_1.getEnv)("BASE_SOCKET_URL")}/apps/list`, query: { targetId, perso, livecommonversion: package_json_1.version, }, }), }).pipe(remapSocketError("listInstalledApps"), (0, operators_1.map)(o => { if (o.type === "result") { return { type: "result", payload: [...o.payload].map(a => { (0, invariant_1.default)(typeof a === "object" && a, "payload array item are objects"); const { hash, name, hash_code_data } = a; (0, invariant_1.default)(typeof hash === "string", "hash is defined"); (0, invariant_1.default)(typeof name === "string", "name is defined"); return { hash, name, hash_code_data, }; }), }; } return o; })); }; const installMcu = (transport, context, { targetId, version, }) => { if ((0, live_env_1.getEnv)("MOCK")) { return (0, socket_mock_1.createMockSocket)((0, socket_mock_1.secureChannelMock)(false), (0, socket_mock_1.bulkSocketMock)(5000)); } (0, logs_1.log)("manager", "installMCU " + context, { targetId, version, }); return (0, socket_1.createDeviceSocket)(transport, { url: url_1.default.format({ pathname: `${(0, live_env_1.getEnv)("BASE_SOCKET_URL")}/mcu`, query: { targetId, version, livecommonversion: package_json_1.version, }, }), unresponsiveExpectedDuringBulk: true, }).pipe(remapSocketError(context)); }; async function retrieveMcuVersion({ mcu_versions, }) { const mcus = await (0, fetchMcusUseCase_1.fetchMcusUseCase)(); const provider = (0, provider_1.getProviderId)(undefined); const availableMcus = mcus.filter(({ id, providers, from_bootloader_version }) => providers.includes(provider) && from_bootloader_version !== "none" && mcu_versions.includes(id)); return findBestMCU(availableMcus); } const API = { /** @deprecated use getAppsCatalogForDevice (from ledger-live-common/src/device/use-cases) instead */ listApps, listInstalledApps, listCategories, getLanguagePackagesForDevice, getCurrentOSU, compatibleMCUForDeviceInfo, findBestMCU, getCurrentFirmware, getFinalFirmwareById, getDeviceVersion, install, genuineCheck, installMcu, retrieveMcuVersion, }; exports.default = API; //# sourceMappingURL=api.js.map