Browse Source

Merge pull request #1815 from valpinkman/feat/onboarding-init-nanox

Onboarding LL with a new Nano X
develop
Gaëtan Renaudeau 6 years ago
committed by GitHub
parent
commit
5ea1adce5a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      src/components/Onboarding/index.js
  2. 6
      src/components/Onboarding/steps/Analytics.js
  3. 7
      src/components/Onboarding/steps/Finish.js
  4. 23
      src/components/Onboarding/steps/GenuineCheck/GenuineCheckErrorPage.js
  5. 7
      src/components/Onboarding/steps/GenuineCheck/GenuineCheckUnavailable.js
  6. 7
      src/components/Onboarding/steps/GenuineCheck/index.js
  7. 41
      src/components/Onboarding/steps/SelectDevice.js
  8. 82
      src/components/Onboarding/steps/SelectPIN/SelectPINRestoreNanoX.js
  9. 81
      src/components/Onboarding/steps/SelectPIN/SelectPINnanoX.js
  10. 24
      src/components/Onboarding/steps/SelectPIN/index.js
  11. 4
      src/components/Onboarding/steps/SetPassword.js
  12. 2
      src/components/Onboarding/steps/WriteSeed/WriteSeedRestore.js
  13. 8
      src/components/Onboarding/steps/WriteSeed/index.js
  14. 12
      src/reducers/onboarding.js
  15. 21
      static/i18n/en/app.json
  16. 0
      static/images/ledger-nano-s-onb.svg
  17. 8
      static/images/ledger-nano-x-onb.svg
  18. 33
      static/images/nano-x-error-onb.svg
  19. 24
      static/images/select-pin-nano-x-onb.svg

6
src/components/Onboarding/index.js

@ -19,7 +19,7 @@ import {
prevStep,
jumpStep,
updateGenuineCheck,
isLedgerNano,
deviceModelId,
flowType,
relaunchOnboarding,
onboardingRelaunchedSelector,
@ -102,7 +102,7 @@ export type StepProps = {
getDeviceInfo: Function,
updateGenuineCheck: Function,
openModal: Function,
isLedgerNano: Function,
deviceModelId: Function,
flowType: Function,
}
@ -171,7 +171,7 @@ class Onboarding extends PureComponent<Props> {
settings,
updateGenuineCheck,
openModal,
isLedgerNano,
deviceModelId,
flowType,
prevStep,
nextStep,

6
src/components/Onboarding/steps/Analytics.js

@ -3,6 +3,8 @@
import React, { PureComponent } from 'react'
import styled from 'styled-components'
import { connect } from 'react-redux'
import { getDeviceModel } from '@ledgerhq/devices'
import { saveSettings } from 'actions/settings'
import Box from 'components/base/Box'
import Switch from 'components/base/Switch'
@ -67,13 +69,15 @@ class Analytics extends PureComponent<StepProps, State> {
const { nextStep, t, onboarding } = this.props
const { analyticsToggle, sentryLogsToggle } = this.state
const model = getDeviceModel(onboarding.deviceModelId)
return (
<FixedTopContainer>
<TrackPage
category="Onboarding"
name="Analytics"
flowType={onboarding.flowType}
deviceType={onboarding.isLedgerNano ? 'Nano S' : 'Blue'}
deviceType={model.productName}
/>
<StepContainerInner>
<Title data-e2e="onboarding_title">{t('onboarding.analytics.title')}</Title>

7
src/components/Onboarding/steps/Finish.js

@ -3,6 +3,8 @@
import React, { Component } from 'react'
import { openURL } from 'helpers/linking'
import styled from 'styled-components'
import { getDeviceModel } from '@ledgerhq/devices'
import { i } from 'helpers/staticPath'
import { urls } from 'config/urls'
@ -66,13 +68,16 @@ export default class Finish extends Component<StepProps, *> {
render() {
const { finish, t, onboarding } = this.props
const { emit } = this.state
const model = getDeviceModel(onboarding.deviceModelId)
return (
<Box sticky justifyContent="center">
<TrackPage
category="Onboarding"
name="Finish"
flowType={onboarding.flowType}
deviceType={onboarding.isLedgerNano ? 'Nano S' : 'Blue'}
deviceType={model.productName}
/>
<ConfettiLayer>
<ConfettiParty emit={emit} />

23
src/components/Onboarding/steps/GenuineCheck/GenuineCheckErrorPage.js

@ -11,9 +11,21 @@ import Box from 'components/base/Box'
import Button from 'components/base/Button'
import ExternalLinkButton from 'components/base/ExternalLinkButton'
import TrackPage from 'analytics/TrackPage'
import { getDeviceModel } from '@ledgerhq/devices'
import { Title, Description, OnboardingFooterWrapper } from '../../helperComponents'
const Img = ({ type }: { type: string }) => {
switch (type) {
case 'blue':
return <img alt="" src={i('blue-error-onb.svg')} />
case 'nanoX':
return <img alt="" src={i('nano-x-error-onb.svg')} />
default:
return <img alt="" src={i('nano-error-onb.svg')} />
}
}
type Props = {
t: T,
redoGenuineCheck: () => void,
@ -23,12 +35,15 @@ type Props = {
class GenuineCheckErrorPage extends PureComponent<Props, *> {
trackErrorPage = (page: string) => {
const { onboarding } = this.props
const model = getDeviceModel(onboarding.deviceModelId)
return (
<TrackPage
category="Onboarding"
name={`Genuine Check Error Page - ${page}`}
flowType={onboarding.flowType}
deviceType={onboarding.isLedgerNano ? 'Nano S' : 'Blue'}
deviceType={model.productName}
/>
)
}
@ -59,11 +74,7 @@ class GenuineCheckErrorPage extends PureComponent<Props, *> {
</Fragment>
)}
<Box mt={5} mr={7}>
{onboarding.isLedgerNano ? (
<img alt="" src={i('nano-error-onb.svg')} />
) : (
<img alt="" src={i('blue-error-onb.svg')} />
)}
<Img type={onboarding.deviceModelId} />
</Box>
</Fragment>
)

7
src/components/Onboarding/steps/GenuineCheck/GenuineCheckUnavailable.js

@ -1,8 +1,9 @@
// @flow
import React from 'react'
import { colors } from 'styles/theme'
import { getDeviceModel } from '@ledgerhq/devices'
import { colors } from 'styles/theme'
import type { T } from 'types/common'
import type { OnboardingState } from 'reducers/onboarding'
@ -54,6 +55,8 @@ export function GenuineCheckUnavailableMessage({
t: T,
onboarding: OnboardingState,
}) {
const model = getDeviceModel(onboarding.deviceModelId)
return (
<Box
horizontal
@ -76,7 +79,7 @@ export function GenuineCheckUnavailableMessage({
handleOpenGenuineCheckModal()
track('Genuine Check Retry', {
flowType: onboarding.flowType,
deviceType: onboarding.isLedgerNano ? 'Nano S' : 'Blue',
deviceType: model.productName,
})
}}
>

7
src/components/Onboarding/steps/GenuineCheck/index.js

@ -3,8 +3,9 @@
import React, { PureComponent } from 'react'
import { connect } from 'react-redux'
import styled from 'styled-components'
import { colors } from 'styles/theme'
import { getDeviceModel } from '@ledgerhq/devices'
import { colors } from 'styles/theme'
import { updateGenuineCheck } from 'reducers/onboarding'
import Box from 'components/base/Box'
@ -165,13 +166,15 @@ class GenuineCheck extends PureComponent<StepProps, State> {
return this.renderGenuineFail()
}
const model = getDeviceModel(onboarding.deviceModelId)
return (
<FixedTopContainer>
<TrackPage
category="Onboarding"
name="Genuine Check"
flowType={onboarding.flowType}
deviceType={onboarding.isLedgerNano ? 'Nano S' : 'Blue'}
deviceType={model.productName}
/>
<StepContainerInner>
<Title>{t('onboarding.genuineCheck.title')}</Title>

41
src/components/Onboarding/steps/SelectDevice.js

@ -3,11 +3,14 @@
import React, { PureComponent } from 'react'
import styled from 'styled-components'
import { connect } from 'react-redux'
import { getDeviceModel } from '@ledgerhq/devices'
import { i } from 'helpers/staticPath'
import { rgba } from 'styles/helpers'
import { isLedgerNano } from 'reducers/onboarding'
import { deviceModelId } from 'reducers/onboarding'
import type { DeviceModelId } from 'reducers/onboarding'
import Box from 'components/base/Box'
import TrackPage from 'analytics/TrackPage'
@ -19,11 +22,11 @@ import OnboardingFooter from '../OnboardingFooter'
import type { StepProps } from '..'
const mapDispatchToProps = { isLedgerNano }
const mapDispatchToProps = { deviceModelId }
class SelectDevice extends PureComponent<StepProps, {}> {
handleIsLedgerNano = (isLedgerNano: boolean) => {
this.props.isLedgerNano(isLedgerNano)
handleDeviceModelId = (deviceModelId: DeviceModelId) => {
this.props.deviceModelId(deviceModelId)
}
handleContinue = () => {
@ -46,24 +49,34 @@ class SelectDevice extends PureComponent<StepProps, {}> {
<Box pt={4}>
<Inner>
<DeviceContainer
isActive={onboarding.isLedgerNano}
onClick={() => this.handleIsLedgerNano(true)}
isActive={onboarding.deviceModelId === 'nanoX'}
onClick={() => this.handleDeviceModelId('nanoX')}
>
{onboarding.deviceModelId === 'nanoX' && <DeviceSelected />}
<DeviceIcon>
<img alt="" src={i('ledger-nano-x-onb.svg')} />
</DeviceIcon>
<BlockTitle>{getDeviceModel('nanoX').productName}</BlockTitle>
</DeviceContainer>
<DeviceContainer
isActive={onboarding.deviceModelId === 'nanoS'}
onClick={() => this.handleDeviceModelId('nanoS')}
>
{onboarding.isLedgerNano && <DeviceSelected />}
{onboarding.deviceModelId === 'nanoS' && <DeviceSelected />}
<DeviceIcon>
<img alt="" src={i('ledger-nano-onb.svg')} />
<img alt="" src={i('ledger-nano-s-onb.svg')} />
</DeviceIcon>
<BlockTitle>{t('onboarding.selectDevice.ledgerNanoCard.title')}</BlockTitle>
<BlockTitle>{getDeviceModel('nanoS').productName}</BlockTitle>
</DeviceContainer>
<DeviceContainer
isActive={!onboarding.isLedgerNano && onboarding.isLedgerNano !== null}
onClick={() => this.handleIsLedgerNano(false)}
isActive={onboarding.deviceModelId === 'blue'}
onClick={() => this.handleDeviceModelId('blue')}
>
{!onboarding.isLedgerNano && onboarding.isLedgerNano !== null && <DeviceSelected />}
{onboarding.deviceModelId === 'blue' && <DeviceSelected />}
<DeviceIcon>
<img alt="" src={i('ledger-blue-onb.svg')} />
</DeviceIcon>
<BlockTitle>{t('onboarding.selectDevice.ledgerBlueCard.title')}</BlockTitle>
<BlockTitle>{getDeviceModel('blue').productName}</BlockTitle>
</DeviceContainer>
</Inner>
</Box>
@ -73,7 +86,7 @@ class SelectDevice extends PureComponent<StepProps, {}> {
t={t}
nextStep={this.handleContinue}
prevStep={() => jumpStep('init')}
isContinueDisabled={onboarding.isLedgerNano === null}
isContinueDisabled={onboarding.deviceModelId === ''}
/>
</FixedTopContainer>
)

82
src/components/Onboarding/steps/SelectPIN/SelectPINRestoreNanoX.js

@ -0,0 +1,82 @@
// @flow
import React, { PureComponent } from 'react'
import { translate } from 'react-i18next'
import { colors } from 'styles/theme'
import { i } from 'helpers/staticPath'
import Box from 'components/base/Box'
import type { T } from 'types/common'
import IconChevronRight from 'icons/ChevronRight'
import { IconOptionRow, DisclaimerBox, OptionRow, Inner } from '../../helperComponents'
type Props = {
t: T,
}
class SelectPINrestoreNanoX extends PureComponent<Props, *> {
render() {
const { t } = this.props
const stepsLedgerNano = [
{
key: 'step1',
icon: <IconOptionRow>{'1.'}</IconOptionRow>,
desc: t('onboarding.selectPIN.restore.instructions.nanoX.step1'),
},
{
key: 'step2',
icon: <IconOptionRow>{'2.'}</IconOptionRow>,
desc: t('onboarding.selectPIN.restore.instructions.nanoX.step2'),
},
{
key: 'step3',
icon: <IconOptionRow>{'3.'}</IconOptionRow>,
desc: t('onboarding.selectPIN.restore.instructions.nanoX.step3'),
},
{
key: 'step4',
icon: <IconOptionRow>{'4.'}</IconOptionRow>,
desc: t('onboarding.selectPIN.restore.instructions.nanoX.step4'),
},
{
key: 'step5',
icon: <IconOptionRow>{'5.'}</IconOptionRow>,
desc: t('onboarding.selectPIN.restore.instructions.nanoX.step5'),
},
]
const disclaimerNotes = [
{
key: 'note1',
icon: <IconChevronRight size={12} style={{ color: colors.smoke }} />,
desc: t('onboarding.selectPIN.disclaimer.note1'),
},
{
key: 'note2',
icon: <IconChevronRight size={12} style={{ color: colors.smoke }} />,
desc: t('onboarding.selectPIN.disclaimer.note2'),
},
{
key: 'note3',
icon: <IconChevronRight size={12} style={{ color: colors.smoke }} />,
desc: t('onboarding.selectPIN.disclaimer.note3'),
},
]
return (
<Box align="center" mt={3}>
<Inner style={{ width: 700 }}>
<img alt="" src={i('select-pin-nano-x-onb.svg')} />
<Box shrink grow flow={4} style={{ marginLeft: 40 }}>
{stepsLedgerNano.map(step => <OptionRow key={step.key} step={step} />)}
</Box>
</Inner>
<DisclaimerBox mt={6} disclaimerNotes={disclaimerNotes} />
</Box>
)
}
}
export default translate()(SelectPINrestoreNanoX)

81
src/components/Onboarding/steps/SelectPIN/SelectPINnanoX.js

@ -0,0 +1,81 @@
// @flow
import React, { PureComponent } from 'react'
import { translate, Trans } from 'react-i18next'
import { colors } from 'styles/theme'
import { i } from 'helpers/staticPath'
import Box from 'components/base/Box'
import type { T } from 'types/common'
import IconChevronRight from 'icons/ChevronRight'
import { IconOptionRow, DisclaimerBox, OptionRow, Inner } from '../../helperComponents'
type Props = {
t: T,
}
class SelectPINnanoX extends PureComponent<Props, *> {
render() {
const { t } = this.props
const stepsLedgerNano = [
{
key: 'step1',
icon: <IconOptionRow>{'1.'}</IconOptionRow>,
desc: t('onboarding.selectPIN.initialize.instructions.nanoX.step1'),
},
{
key: 'step2',
icon: <IconOptionRow>{'2.'}</IconOptionRow>,
desc: (
<Box style={{ display: 'block' }}>
<Trans i18nKey="onboarding.selectPIN.initialize.instructions.nanoX.step2" />
</Box>
),
},
{
key: 'step3',
icon: <IconOptionRow>{'3.'}</IconOptionRow>,
desc: t('onboarding.selectPIN.initialize.instructions.nanoX.step3'),
},
{
key: 'step4',
icon: <IconOptionRow>{'4.'}</IconOptionRow>,
desc: t('onboarding.selectPIN.initialize.instructions.nanoX.step4'),
},
]
const disclaimerNotes = [
{
key: 'note1',
icon: <IconChevronRight size={12} style={{ color: colors.smoke }} />,
desc: t('onboarding.selectPIN.disclaimer.note1'),
},
{
key: 'note2',
icon: <IconChevronRight size={12} style={{ color: colors.smoke }} />,
desc: t('onboarding.selectPIN.disclaimer.note2'),
},
{
key: 'note3',
icon: <IconChevronRight size={12} style={{ color: colors.smoke }} />,
desc: t('onboarding.selectPIN.disclaimer.note3'),
},
]
return (
<Box align="center" mt={3}>
<Inner style={{ width: 700 }}>
<img alt="" src={i('select-pin-nano-x-onb.svg')} />
<Box shrink grow flow={4} style={{ marginLeft: 40 }}>
{stepsLedgerNano.map(step => <OptionRow key={step.key} step={step} />)}
</Box>
</Inner>
<DisclaimerBox mt={6} disclaimerNotes={disclaimerNotes} />
</Box>
)
}
}
export default translate()(SelectPINnanoX)

24
src/components/Onboarding/steps/SelectPIN/index.js

@ -1,23 +1,39 @@
// @flow
import React from 'react'
import { getDeviceModel } from '@ledgerhq/devices'
import Box from 'components/base/Box'
import TrackPage from 'analytics/TrackPage'
import type { DeviceModelId } from 'reducers/onboarding'
import GrowScroll from 'components/base/GrowScroll'
import { Title, FixedTopContainer } from '../../helperComponents'
import OnboardingFooter from '../../OnboardingFooter'
import SelectPINnano from './SelectPINnano'
import SelectPINblue from './SelectPINblue'
import SelectPINnanoX from './SelectPINnanoX'
import SelectPINrestoreNano from './SelectPINrestoreNano'
import SelectPINRestoreNanoX from './SelectPINRestoreNanoX'
import SelectPINrestoreBlue from './SelectPINrestoreBlue'
import type { StepProps } from '../..'
const SelectPin = ({ modelId, restore = false }: { modelId: DeviceModelId, restore?: boolean }) => {
switch (modelId) {
case 'nanoX':
return restore ? <SelectPINRestoreNanoX /> : <SelectPINnanoX />
case 'blue':
return restore ? <SelectPINrestoreBlue /> : <SelectPINblue />
default:
return restore ? <SelectPINrestoreNano /> : <SelectPINnano />
}
}
export default (props: StepProps) => {
const { nextStep, prevStep, t, onboarding } = props
const model = getDeviceModel(onboarding.deviceModelId)
return (
<FixedTopContainer>
<GrowScroll pb={7}>
@ -25,20 +41,20 @@ export default (props: StepProps) => {
category="Onboarding"
name="Choose PIN"
flowType={onboarding.flowType}
deviceType={onboarding.isLedgerNano ? 'Nano S' : 'Blue'}
deviceType={model.productName}
/>
{onboarding.flowType === 'restoreDevice' ? (
<Box grow alignItems="center">
<Title>{t('onboarding.selectPIN.restore.title')}</Title>
<Box align="center" mt={7}>
{onboarding.isLedgerNano ? <SelectPINrestoreNano /> : <SelectPINrestoreBlue />}
<SelectPin modelId={onboarding.deviceModelId} restore />
</Box>
</Box>
) : (
<Box grow alignItems="center">
<Title>{t('onboarding.selectPIN.initialize.title')}</Title>
<Box align="center" mt={7}>
{onboarding.isLedgerNano ? <SelectPINnano /> : <SelectPINblue />}
<SelectPin modelId={onboarding.deviceModelId} />
</Box>
</Box>
)}

4
src/components/Onboarding/steps/SetPassword.js

@ -2,6 +2,8 @@
import React, { PureComponent, Fragment } from 'react'
import { connect } from 'react-redux'
import { getDeviceModel } from '@ledgerhq/devices'
import { colors } from 'styles/theme'
import db from 'helpers/db'
@ -105,7 +107,7 @@ class SetPassword extends PureComponent<Props, State> {
category="Onboarding"
name="Set Password"
flowType={onboarding.flowType}
deviceType={onboarding.isLedgerNano ? 'Nano S' : 'Blue'}
deviceType={getDeviceModel(onboarding.deviceModelId).productName}
/>
<StepContainerInner>
<Fragment>

2
src/components/Onboarding/steps/WriteSeed/WriteSeedRestore.js

@ -123,7 +123,7 @@ class WriteSeedRestore extends PureComponent<Props, *> {
<Box style={{ width: 260, justifyContent: 'center', alignItems: 'center' }}>
<img alt="" src={i('write-seed-onb.svg')} />
</Box>
{onboarding.isLedgerNano ? (
{onboarding.deviceModelId === 'nanoS' ? (
<Box shrink flow={2} m={0}>
{stepsNano.map(step => <OptionRow key={step.key} step={step} />)}
</Box>

8
src/components/Onboarding/steps/WriteSeed/index.js

@ -1,7 +1,7 @@
// @flow
import React from 'react'
import { getDeviceModel } from '@ledgerhq/devices'
import Box from 'components/base/Box'
import TrackPage from 'analytics/TrackPage'
@ -17,6 +17,8 @@ import type { StepProps } from '../..'
export default (props: StepProps) => {
const { nextStep, prevStep, t, onboarding } = props
const model = getDeviceModel(onboarding.deviceModelId)
return (
<FixedTopContainer>
<GrowScroll pb={7}>
@ -24,12 +26,12 @@ export default (props: StepProps) => {
category="Onboarding"
name="Recovery Phase"
flowType={onboarding.flowType}
deviceType={onboarding.isLedgerNano ? 'Nano S' : 'Blue'}
deviceType={model.productName}
/>
<Box grow alignItems="center">
{onboarding.flowType === 'restoreDevice' ? (
<WriteSeedRestore onboarding={onboarding} />
) : onboarding.isLedgerNano ? (
) : onboarding.deviceModelId === 'nanoS' ? (
<WriteSeedNano />
) : (
<WriteSeedBlue />

12
src/reducers/onboarding.js

@ -15,6 +15,8 @@ type Step = {
},
}
export type DeviceModelId = 'nanoX' | 'nanoS' | 'blue' | ''
export type OnboardingState = {
stepIndex: number,
stepName: string, // TODO: specify that the string comes from Steps type
@ -27,7 +29,7 @@ export type OnboardingState = {
genuineCheckUnavailable: ?Error,
displayErrorScreen: boolean,
},
isLedgerNano: boolean | null,
deviceModelId: DeviceModelId,
flowType: string,
onboardingRelaunched?: boolean,
}
@ -43,7 +45,7 @@ const initialState: OnboardingState = {
genuineCheckUnavailable: null,
displayErrorScreen: false,
},
isLedgerNano: null,
deviceModelId: '',
flowType: '',
onboardingRelaunched: false,
steps: [
@ -167,9 +169,9 @@ const handlers = {
...state,
flowType,
}),
ONBOARDING_SET_DEVICE_TYPE: (state: OnboardingState, { payload: isLedgerNano }) => ({
ONBOARDING_SET_DEVICE_TYPE: (state: OnboardingState, { payload: deviceModelId }) => ({
...state,
isLedgerNano,
deviceModelId,
}),
ONBOARDING_RELAUNCH: (state: OnboardingState, { payload: onboardingRelaunched }) => ({
...initialState,
@ -187,5 +189,5 @@ export const nextStep = createAction('ONBOARDING_NEXT_STEP')
export const prevStep = createAction('ONBOARDING_PREV_STEP')
export const jumpStep = createAction('ONBOARDING_JUMP_STEP')
export const updateGenuineCheck = createAction('UPDATE_GENUINE_CHECK')
export const isLedgerNano = createAction('ONBOARDING_SET_DEVICE_TYPE')
export const deviceModelId = createAction('ONBOARDING_SET_DEVICE_TYPE')
export const flowType = createAction('ONBOARDING_SET_FLOW_TYPE')

21
static/i18n/en/app.json

@ -563,13 +563,7 @@
}
},
"selectDevice": {
"title": "Select your device",
"ledgerNanoCard": {
"title": "Ledger Nano S"
},
"ledgerBlueCard": {
"title": "Ledger Blue"
}
"title": "Select your device"
},
"selectPIN": {
"disclaimer": {
@ -586,6 +580,12 @@
"step3": "Press the left or right button to select a digit. Press both buttons to validate.",
"step4": "Select ✓ to confirm your PIN code. Select ⬅ to erase a digit."
},
"nanoX": {
"step1": "Connect the Ledger Nano X to your computer.",
"step2": "Press both buttons to choose Set up as new device.",
"step3": "Press the left or right button to select a digit.",
"step4": "Select ✓ to confirm your PIN code. Select ⬅ to erase a digit."
},
"blue": {
"step1": "Connect the Ledger Blue to your computer.",
"step2": "Tap on <1><0>Configure as new device</0></1>.",
@ -602,6 +602,13 @@
"step3": "Press the left or right button to select a digit. Press both buttons to validate.",
"step4": "Select ✓ to confirm your PIN code. Select ⬅ to erase a digit."
},
"nanoX": {
"step1": "Connect your Ledger Nano X to your computer.",
"step2": "Press both buttons as instructed on your Ledger Nano X screen.",
"step3": "Press the left button to cancel Configure as new device.",
"step4": "Press the right button to select Restore configuration.",
"step5": "Choose a PIN code between 4 and 8 digits long."
},
"blue": {
"step1": "Connect the Ledger Blue to your computer.",
"step2": "Tap on <1><0>Restore configuration</0></1>.",

0
static/images/ledger-nano-onb.svg → static/images/ledger-nano-s-onb.svg

Before

Width:  |  Height:  |  Size: 931 B

After

Width:  |  Height:  |  Size: 931 B

8
static/images/ledger-nano-x-onb.svg

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="76" viewBox="0 0 14 76">
<g fill="none" fill-rule="evenodd">
<path fill="#6490F1" fill-opacity=".1" stroke="#1D2028" stroke-width="1.5" d="M1.6.75a.85.85 0 0 0-.85.85v72.8c0 .47.38.85.85.85h10.8c.47 0 .85-.38.85-.85V1.6a.85.85 0 0 0-.85-.85H1.6z"/>
<path fill="#FFF" stroke="#1D2028" stroke-width="1.5" d="M7 33.321a6.25 6.25 0 0 0-6.25 6.25V74.4c0 .47.38.85.85.85h10.8c.47 0 .85-.38.85-.85V39.571A6.25 6.25 0 0 0 7 33.321z"/>
<ellipse cx="6.995" cy="39.835" fill="#FFF" stroke="#6490F1" stroke-width=".5" rx="3.295" ry="3.256"/>
<ellipse cx="6.993" cy="7.004" stroke="#6490F1" stroke-width=".5" rx="3.293" ry="3.254"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 731 B

33
static/images/nano-x-error-onb.svg

@ -0,0 +1,33 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="379" height="42" viewBox="0 0 379 42">
<defs>
<linearGradient id="a" x1="50%" x2="50%" y1="0%" y2="100%">
<stop offset="0%"/>
<stop offset="100%" stop-color="#FFF"/>
</linearGradient>
<rect id="b" width="41.711" height="238.384" rx="4"/>
<path id="c" d="M5.773 5l2.541-2.541a.235.235 0 0 0 0-.332l-.441-.441a.235.235 0 0 0-.332 0L5 4.226l-2.541-2.54a.235.235 0 0 0-.332 0l-.441.441a.235.235 0 0 0 0 .332L4.226 5l-2.54 2.541a.235.235 0 0 0 0 .332l.441.441c.092.092.24.092.332 0L5 5.774l2.541 2.54c.092.092.24.092.332 0l.441-.441a.235.235 0 0 0 0-.332L5.774 5z"/>
</defs>
<g fill="none" fill-rule="evenodd">
<path stroke="#1D2027" stroke-width="2" d="M127.356 29a1 1 0 0 1-1 1H100.13a5 5 0 0 1-5-5v-8.486a5 5 0 0 1 5-5h26.225a1 1 0 0 1 1 1V29z"/>
<path stroke="#142533" stroke-width="2" d="M94.747 23.792H83.818v-6.436h10.93v6.436z"/>
<path stroke="#1D2027" stroke-width="2" d="M127.423 26.287V15.032l6.977.082a1 1 0 0 1 .988 1V25.381a1 1 0 0 1-1.012.988l-6.953-.082z"/>
<path fill="url(#a)" d="M6.836 53.925h1.616v82.65H6.836v-82.65zm5.657 0h1.616v82.65h-1.616v-82.65z" transform="matrix(0 -1 -1 0 137 31)"/>
<g transform="rotate(-90 84.5 -42.5)">
<use fill="#FFF" xlink:href="#b"/>
<rect width="39.711" height="236.384" x="1" y="1" fill="#FCE0E4" stroke="#142533" stroke-linejoin="square" stroke-width="2" rx="4"/>
<path fill="#FFF" stroke="#EA2E49" d="M10.6 44.5a1.1 1.1 0 0 0-1.1 1.1v50.8a1.1 1.1 0 0 0 1.1 1.1h20.8a1.1 1.1 0 0 0 1.1-1.1V45.6a1.1 1.1 0 0 0-1.1-1.1H10.6z"/>
<path fill="#FFF" stroke="#142533" stroke-width="2" d="M20.856 108.966C9.89 108.966 1 117.856 1 128.822v118.562a3 3 0 0 0 3 3h33.711a3 3 0 0 0 3-3V128.822c0-10.966-8.89-19.856-19.855-19.856z"/>
<ellipse cx="21.016" cy="129.123" stroke="#EA2E49" rx="10.57" ry="10.644"/>
<ellipse cx="21.016" cy="21.123" stroke="#EA2E49" rx="10.57" ry="10.644"/>
<g transform="translate(16 66)">
<mask id="d" fill="#fff">
<use xlink:href="#c"/>
</mask>
<use fill="#000" fill-rule="nonzero" xlink:href="#c"/>
<g fill="#EA2E49" mask="url(#d)">
<path d="M0 0h10v10H0z"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

24
static/images/select-pin-nano-x-onb.svg

@ -0,0 +1,24 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="264" height="128" viewBox="0 0 264 128">
<defs>
<linearGradient id="a" x1="50%" x2="50%" y1="0%" y2="100%">
<stop offset="0%"/>
<stop offset="100%" stop-color="#FFF"/>
</linearGradient>
<path id="b" d="M91 0h34a4 4 0 0 1 4 4v118.144c0 11.519-9.337 20.856-20.856 20.856h-.288C96.337 143 87 133.663 87 122.144V4a4 4 0 0 1 4-4z"/>
</defs>
<g fill="none" fill-rule="evenodd">
<path stroke="#1D2027" stroke-width="2" d="M127.856 30.44a1 1 0 0 1-1 1H100.63a5 5 0 0 1-5-5v-8.486a5 5 0 0 1 5-5h26.225a1 1 0 0 1 1 1v16.485z"/>
<path stroke="#142533" stroke-width="2" d="M95.247 25.231H84.318v-6.435h10.93v6.435z"/>
<path stroke="#1D2027" stroke-width="2" d="M127.923 27.726V16.471l6.977.083a1 1 0 0 1 .988 1V26.82a1 1 0 0 1-1.012.988l-6.953-.083z"/>
<path fill="url(#a)" d="M6.836 53.925h1.616v82.65H6.836v-82.65zm5.657 0h1.616v82.65h-1.616v-82.65z" transform="matrix(0 -1 -1 0 137.5 32.44)"/>
<g transform="rotate(-90 125.09 4.475)">
<use fill="#FFF" xlink:href="#b"/>
<path fill="#6490F1" fill-opacity=".15" stroke="#142533" stroke-linejoin="square" stroke-width="2" d="M91 1a3 3 0 0 0-3 3v118.144C88 133.11 96.89 142 107.856 142h.288C119.11 142 128 133.11 128 122.144V4a3 3 0 0 0-3-3H91z"/>
<path fill="#FFF" stroke="#6490F1" d="M97.6 41.5a1.1 1.1 0 0 0-1.1 1.1v52.8a1.1 1.1 0 0 0 1.1 1.1h20.8a1.1 1.1 0 0 0 1.1-1.1V42.6a1.1 1.1 0 0 0-1.1-1.1H97.6z"/>
<path fill="#6490F1" d="M105.5 51h5a.5.5 0 0 1 .5.5v34a.5.5 0 0 1-.5.5h-5a.5.5 0 0 1-.5-.5v-34a.5.5 0 0 1 .5-.5zm1.238 3.042l.774.512v.013l-.774.505.341.466.722-.577h.013l.243.899.551-.177-.328-.88.932.053v-.597l-.932.046.328-.873-.551-.17-.243.892h-.013l-.722-.584-.34.472zm0 3.908l.774.512v.013l-.774.505.341.466.722-.578h.013l.243.9.551-.178-.328-.88.932.053v-.597l-.932.046.328-.872-.551-.17-.243.891h-.013l-.722-.584-.34.473zm0 3.907l.774.512v.013l-.774.505.341.466.722-.577h.013l.243.899.551-.178-.328-.879.932.053v-.597l-.932.046.328-.873-.551-.17-.243.892h-.013l-.722-.584-.34.472zm0 3.908l.774.511v.014l-.774.505.341.466.722-.578h.013l.243.899.551-.177-.328-.88.932.053v-.597l-.932.046.328-.872-.551-.171-.243.892h-.013l-.722-.584-.34.473zm0 3.907l.774.512v.013l-.774.505.341.466.722-.577h.013l.243.898.551-.177-.328-.879.932.053v-.597l-.932.046.328-.873-.551-.17-.243.892h-.013l-.722-.584-.34.472zm0 3.908l.774.511v.013l-.774.506.341.465.722-.577h.013l.243.899.551-.177-.328-.88.932.053v-.597l-.932.046.328-.873-.551-.17-.243.892h-.013l-.722-.584-.34.473zm0 3.907l.774.512v.013l-.774.505.341.466.722-.578h.013l.243.9.551-.178-.328-.879.932.052v-.597l-.932.046.328-.872-.551-.17-.243.891h-.013l-.722-.583-.34.472zm0 3.907l.774.512v.013l-.774.505.341.466.722-.577h.013l.243.899.551-.177-.328-.88.932.053v-.597l-.932.046.328-.873-.551-.17-.243.892h-.013l-.722-.584-.34.472z"/>
<path fill="#FFF" stroke="#142533" stroke-width="2" d="M123.166 135.105c7.049-8.4 5.953-20.925-2.447-27.974l-90.824-76.21a3 3 0 0 0-4.227.37L4 57.115a3 3 0 0 0 .37 4.227l90.824 76.21c8.4 7.049 20.924 5.953 27.973-2.447z"/>
<ellipse cx="108.016" cy="122.123" stroke="#6490F1" rx="10.57" ry="10.644"/>
<ellipse cx="108.016" cy="22.123" stroke="#6490F1" rx="10.57" ry="10.644"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

Loading…
Cancel
Save