diff --git a/src/commands/index.js b/src/commands/index.js index 7f37b4bb..4700692c 100644 --- a/src/commands/index.js +++ b/src/commands/index.js @@ -22,6 +22,8 @@ import libcoreSignAndBroadcast from 'commands/libcoreSignAndBroadcast' import libcoreSyncAccount from 'commands/libcoreSyncAccount' import libcoreValidAddress from 'commands/libcoreValidAddress' import listApps from 'commands/listApps' +import listAppVersions from 'commands/listAppVersions' +import listCategories from 'commands/listCategories' import listenDevices from 'commands/listenDevices' import signTransaction from 'commands/signTransaction' import testApdu from 'commands/testApdu' @@ -49,6 +51,8 @@ const all: Array> = [ libcoreSyncAccount, libcoreValidAddress, listApps, + listAppVersions, + listCategories, listenDevices, signTransaction, testApdu, diff --git a/src/commands/listAppVersions.js b/src/commands/listAppVersions.js new file mode 100644 index 00000000..494d7168 --- /dev/null +++ b/src/commands/listAppVersions.js @@ -0,0 +1,15 @@ +// @flow + +import { createCommand, Command } from 'helpers/ipc' +import { fromPromise } from 'rxjs/observable/fromPromise' +import type { DeviceInfo } from 'helpers/devices/getDeviceInfo' + +import listAppVersions from 'helpers/apps/listAppVersions' + +type Result = * + +const cmd: Command = createCommand('listAppVersions', deviceInfo => + fromPromise(listAppVersions(deviceInfo)), +) + +export default cmd diff --git a/src/commands/listApps.js b/src/commands/listApps.js index d9e28ee2..f049def3 100644 --- a/src/commands/listApps.js +++ b/src/commands/listApps.js @@ -5,17 +5,10 @@ import { fromPromise } from 'rxjs/observable/fromPromise' import listApps from 'helpers/apps/listApps' -type Input = { - targetId: string | number, - fullVersion: string, - provider: number, -} +type Input = {} type Result = * -const cmd: Command = createCommand( - 'listApps', - ({ targetId, fullVersion, provider }) => fromPromise(listApps(targetId, fullVersion, provider)), -) +const cmd: Command = createCommand('listApps', () => fromPromise(listApps())) export default cmd diff --git a/src/commands/listCategories.js b/src/commands/listCategories.js new file mode 100644 index 00000000..3632a47f --- /dev/null +++ b/src/commands/listCategories.js @@ -0,0 +1,16 @@ +// @flow + +import { createCommand, Command } from 'helpers/ipc' +import { fromPromise } from 'rxjs/observable/fromPromise' + +import listCategories from 'helpers/apps/listCategories' + +type Input = {} + +type Result = * + +const cmd: Command = createCommand('listCategories', () => + fromPromise(listCategories()), +) + +export default cmd diff --git a/src/components/ManagerPage/AppsList.js b/src/components/ManagerPage/AppsList.js index 239e0871..c7b5e833 100644 --- a/src/components/ManagerPage/AppsList.js +++ b/src/components/ManagerPage/AppsList.js @@ -4,11 +4,16 @@ import React, { PureComponent, Fragment } from 'react' import styled from 'styled-components' import { translate } from 'react-i18next' - +import { connect } from 'react-redux' +import { compose } from 'redux' import type { Device, T } from 'types/common' import type { LedgerScriptParams } from 'helpers/common' +import type { DeviceInfo } from 'helpers/devices/getDeviceInfo' +import { developerModeSelector } from 'reducers/settings' import listApps from 'commands/listApps' +import listAppVersions from 'commands/listAppVersions' + import installApp from 'commands/installApp' import uninstallApp from 'commands/uninstallApp' @@ -30,6 +35,10 @@ import CheckCircle from 'icons/CheckCircle' import ManagerApp from './ManagerApp' import AppSearchBar from './AppSearchBar' +const mapStateToProps = state => ({ + isDevMode: developerModeSelector(state), +}) + const List = styled(Box).attrs({ horizontal: true, m: -3, @@ -46,16 +55,15 @@ type Mode = 'home' | 'installing' | 'uninstalling' type Props = { device: Device, - targetId: string | number, + deviceInfo: DeviceInfo, t: T, - fullVersion: string, - provider: number, + isDevMode: boolean, } type State = { status: Status, error: ?Error, - appsList: LedgerScriptParams[], + filteredAppVersionsList: LedgerScriptParams[], appsLoaded: boolean, app: string, mode: Mode, @@ -65,7 +73,7 @@ class AppsList extends PureComponent { state = { status: 'loading', error: null, - appsList: [], + filteredAppVersionsList: [], appsLoaded: false, app: '', mode: 'home', @@ -81,12 +89,31 @@ class AppsList extends PureComponent { _unmounted = false + filterAppVersions = (applicationsList, compatibleAppVersionsList) => { + if (!this.props.isDevMode) { + return compatibleAppVersionsList.filter( + version => applicationsList.find(e => e.id === version.app).category !== 2, + ) + } + return applicationsList + } + async fetchAppList() { try { - const { targetId, fullVersion, provider } = this.props - const appsList = await listApps.send({ targetId, fullVersion, provider }).toPromise() + const { deviceInfo } = this.props + const applicationsList = await listApps.send({}).toPromise() + const compatibleAppVersionsList = await listAppVersions.send(deviceInfo).toPromise() + const filteredAppVersionsList = this.filterAppVersions( + applicationsList, + compatibleAppVersionsList, + ) + if (!this._unmounted) { - this.setState({ appsList, status: 'idle', appsLoaded: true }) + this.setState({ + status: 'idle', + filteredAppVersionsList, + appsLoaded: true, + }) } } catch (err) { this.setState({ status: 'error', error: err }) @@ -98,9 +125,9 @@ class AppsList extends PureComponent { try { const { device: { path: devicePath }, - targetId, + deviceInfo, } = this.props - const data = { app, devicePath, targetId } + const data = { app, devicePath, targetId: deviceInfo.targetId } await installApp.send(data).toPromise() this.setState({ status: 'success' }) } catch (err) { @@ -113,9 +140,9 @@ class AppsList extends PureComponent { try { const { device: { path: devicePath }, - targetId, + deviceInfo, } = this.props - const data = { app, devicePath, targetId } + const data = { app, devicePath, targetId: deviceInfo.targetId } await uninstallApp.send(data).toPromise() this.setState({ status: 'success' }) } catch (err) { @@ -214,10 +241,10 @@ class AppsList extends PureComponent { } renderList() { - const { appsList, appsLoaded } = this.state + const { filteredAppVersionsList, appsLoaded } = this.state return appsLoaded ? ( - + {items => ( {items.map(c => ( @@ -268,4 +295,7 @@ class AppsList extends PureComponent { } } -export default translate()(AppsList) +export default compose( + translate(), + connect(mapStateToProps), +)(AppsList) diff --git a/src/helpers/apps/listAppVersions.js b/src/helpers/apps/listAppVersions.js new file mode 100644 index 00000000..c340a200 --- /dev/null +++ b/src/helpers/apps/listAppVersions.js @@ -0,0 +1,31 @@ +// @flow +import network from 'api/network' +import type { DeviceInfo } from 'helpers/devices/getDeviceInfo' + +import { APPLICATIONS_BY_DEVICE } from 'helpers/urls' +import getDeviceVersion from 'helpers/devices/getDeviceVersion' +import getCurrentFirmware from 'helpers/devices/getCurrentFirmware' + +export default async (deviceInfo: DeviceInfo) => { + try { + const deviceData = await getDeviceVersion(deviceInfo.targetId, deviceInfo.providerId) + const firmwareData = await getCurrentFirmware({ + deviceId: deviceData.id, + fullVersion: deviceInfo.fullVersion, + provider: deviceInfo.providerId, + }) + const params = { + provider: deviceInfo.providerId, + current_se_firmware_final_version: firmwareData.id, + device_version: deviceData.id, + } + const { + data: { application_versions }, + } = await network({ method: 'POST', url: APPLICATIONS_BY_DEVICE, data: params }) + return application_versions.length > 0 ? application_versions : [] + } catch (err) { + const error = Error(err.message) + error.stack = err.stack + throw err + } +} diff --git a/src/helpers/apps/listApps.js b/src/helpers/apps/listApps.js index 46333447..7c85e3ee 100644 --- a/src/helpers/apps/listApps.js +++ b/src/helpers/apps/listApps.js @@ -1,27 +1,12 @@ // @flow import network from 'api/network' -import { APPLICATIONS_BY_DEVICE } from 'helpers/urls' -import getDeviceVersion from 'helpers/devices/getDeviceVersion' -import getCurrentFirmware from 'helpers/devices/getCurrentFirmware' +import { GET_APPLICATIONS } from 'helpers/urls' -export default async (targetId: string | number, fullVersion: string, provider: number) => { +export default async () => { try { - const deviceData = await getDeviceVersion(targetId, provider) - const firmwareData = await getCurrentFirmware({ - deviceId: deviceData.id, - fullVersion, - provider, - }) - const params = { - provider, - current_se_firmware_final_version: firmwareData.id, - device_version: deviceData.id, - } - const { - data: { application_versions }, - } = await network({ method: 'POST', url: APPLICATIONS_BY_DEVICE, data: params }) - return application_versions.length > 0 ? application_versions : [] + const { data } = await network({ method: 'GET', url: GET_APPLICATIONS }) + return data.length > 0 ? data : [] } catch (err) { const error = Error(err.message) error.stack = err.stack diff --git a/src/helpers/apps/listCategories.js b/src/helpers/apps/listCategories.js new file mode 100644 index 00000000..494b5cab --- /dev/null +++ b/src/helpers/apps/listCategories.js @@ -0,0 +1,15 @@ +// @flow +import network from 'api/network' + +import { GET_CATEGORIES } from 'helpers/urls' + +export default async () => { + try { + const { data } = await network({ method: 'GET', url: GET_CATEGORIES }) + return data.length > 0 ? data : [] + } catch (err) { + const error = Error(err.message) + error.stack = err.stack + throw err + } +} diff --git a/src/helpers/urls.js b/src/helpers/urls.js index 448eb7c3..6ff24a70 100644 --- a/src/helpers/urls.js +++ b/src/helpers/urls.js @@ -21,6 +21,8 @@ export const GET_CURRENT_FIRMWARE: string = managerUrlbuilder('get_firmware_vers export const GET_CURRENT_OSU: string = managerUrlbuilder('get_osu_version') export const GET_LATEST_FIRMWARE: string = managerUrlbuilder('get_latest_firmware') export const GET_NEXT_MCU: string = managerUrlbuilder('mcu_versions_bootloader') +export const GET_CATEGORIES: string = managerUrlbuilder('categories') +export const GET_APPLICATIONS: string = managerUrlbuilder('applications') export const WS_INSTALL: (arg: LedgerScriptParams) => string = wsURLBuilder('install') export const WS_GENUINE: (arg: {