Browse Source

Merge branch 'develop' into refactor-modal

develop
Juan Cortés Ross 6 years ago
committed by GitHub
parent
commit
9fda79949e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      package.json
  2. 15
      scripts/check-no-dups.sh
  3. 1
      src/bridge/BridgeSyncContext.js
  4. 8
      src/bridge/EthereumJSBridge.js
  5. 8
      src/bridge/LibcoreBridge.js
  6. 20
      src/bridge/RippleJSBridge.js
  7. 2
      src/bridge/makeMockBridge.js
  8. 4
      src/bridge/types.js
  9. BIN
      src/commands/.DS_Store
  10. 84
      src/components/ManagerPage/AppsList.js
  11. 3
      src/components/ManagerPage/ManagerApp.js
  12. 5
      src/components/Onboarding/steps/GenuineCheck/GenuineCheckUnavailable.js
  13. 2
      src/components/SelectExchange.js
  14. 14
      src/components/SettingsPage/RepairDeviceButton.js
  15. 13
      src/components/SettingsPage/sections/Export.js
  16. 4
      src/components/modals/AddAccounts/index.js
  17. 4
      src/components/modals/Receive/index.js
  18. 10
      src/components/modals/Send/fields/RecipientField.js
  19. 4
      src/components/modals/Send/index.js
  20. 2
      src/components/modals/Send/steps/01-step-amount.js
  21. 6
      src/components/modals/UpdateFirmware/index.js
  22. 13
      static/i18n/en/app.json
  23. 90
      yarn.lock

16
package.json

@ -20,7 +20,7 @@
"test-e2e": "jest test-e2e",
"test-sync": "bash test-e2e/sync/launch.sh",
"prettier": "prettier --write \"{src,webpack,.storybook,test-e2e}/**/*.{js,json}\"",
"ci": "yarn lint && yarn flow && yarn prettier && yarn test",
"ci": "yarn check --integrity && ./scripts/check-no-dups.sh && yarn lint && yarn flow && yarn prettier && yarn test",
"storybook": "NODE_ENV=development STORYBOOK_ENV=1 start-storybook -s ./static -p 4444",
"publish-storybook": "bash ./scripts/legacy/publish-storybook.sh",
"reset-files": "bash ./scripts/legacy/reset-files.sh"
@ -35,11 +35,12 @@
}
},
"dependencies": {
"@ledgerhq/hw-app-btc": "^4.34.0",
"@ledgerhq/hw-app-eth": "^4.32.0",
"@ledgerhq/hw-app-xrp": "^4.32.0",
"@ledgerhq/hw-transport": "^4.32.0",
"@ledgerhq/hw-transport-node-hid": "^4.32.0",
"@ledgerhq/errors": "^4.35.1",
"@ledgerhq/hw-app-btc": "^4.35.0",
"@ledgerhq/hw-app-eth": "^4.35.0",
"@ledgerhq/hw-app-xrp": "^4.35.0",
"@ledgerhq/hw-transport": "^4.35.0",
"@ledgerhq/hw-transport-node-hid": "^4.35.0",
"@ledgerhq/ledger-core": "2.0.0-rc.16",
"@ledgerhq/live-common": "4.15.0-beta.0",
"animated": "^0.2.2",
@ -183,7 +184,8 @@
"webpack": "^4.6.0",
"webpack-bundle-analyzer": "^2.11.1",
"webpack-cli": "^2.0.14",
"yaml-loader": "^0.5.0"
"yaml-loader": "^0.5.0",
"yarn-deduplicate": "^1.1.1"
},
"engines": {
"node": ">=8.9.0 <=8.15.0",

15
scripts/check-no-dups.sh

@ -0,0 +1,15 @@
#!/bin/bash
yarn-deduplicate -l | grep \@ledgerhq
if [ $? -eq 0 ]; then
echo "Found duplicates in @ledgerhq/* – fix it with yarn-deduplicate"
exit 1
fi
yarn-deduplicate -l | grep \"react
if [ $? -eq 0 ]; then
echo "Found duplicates in some react packages – fix it with yarn-deduplicate"
exit 1
fi

1
src/bridge/BridgeSyncContext.js

@ -100,6 +100,7 @@ class Provider extends Component<BridgeSyncProviderOwnProps, Sync> {
next()
},
error: error => {
logger.critical(error)
this.props.setAccountSyncState(accountId, { pending: false, error })
next()
},

8
src/bridge/EthereumJSBridge.js

@ -129,7 +129,7 @@ function isRecipientValid(currency, recipient) {
}
// Returns a warning if we detect a non-eip address
function getRecipientWarning(currency, recipient) {
function getRecipientWarning(account, recipient) {
if (!recipient.match(/^0x[0-9a-fA-F]{40}$/)) return null
const slice = recipient.substr(2)
const isFullUpper = slice === slice.toUpperCase()
@ -420,9 +420,9 @@ const EthereumBridge: WalletBridge<Transaction> = {
pullMoreOperations: () => Promise.resolve(a => a), // NOT IMPLEMENTED
isRecipientValid: (currency, recipient) => Promise.resolve(isRecipientValid(currency, recipient)),
getRecipientWarning: (currency, recipient) =>
Promise.resolve(getRecipientWarning(currency, recipient)),
isRecipientValid: (account, recipient) => Promise.resolve(isRecipientValid(account, recipient)),
getRecipientWarning: (account, recipient) =>
Promise.resolve(getRecipientWarning(account, recipient)),
createTransaction: () => ({
amount: BigNumber(0),

8
src/bridge/LibcoreBridge.js

@ -60,15 +60,15 @@ const EditAdvancedOptions = ({ onChange, value }: EditProps<Transaction>) => (
const recipientValidLRU = LRU({ max: 100 })
const isRecipientValid = (currency, recipient) => {
const key = `${currency.id}_${recipient}`
const isRecipientValid = (account, recipient) => {
const key = `${account.currency.id}_${recipient}`
let promise = recipientValidLRU.get(key)
if (promise) return promise
if (!recipient) return Promise.resolve(false)
promise = libcoreValidAddress
.send({
address: recipient,
currencyId: currency.id,
currencyId: account.currency.id,
})
.toPromise()
recipientValidLRU.set(key, promise)
@ -83,7 +83,7 @@ const getFeesKey = (a, t) =>
}`
const getFees = async (a, transaction) => {
const isValid = await isRecipientValid(a.currency, transaction.recipient)
const isValid = await isRecipientValid(a, transaction.recipient)
if (!isValid) return null
const key = getFeesKey(a, transaction)
let promise = feesLRU.get(key)

20
src/bridge/RippleJSBridge.js

@ -34,6 +34,7 @@ import {
NotEnoughBalance,
FeeNotLoaded,
NotEnoughBalanceBecauseDestinationNotCreated,
InvalidAddressBecauseDestinationIsAlsoSource,
} from '@ledgerhq/errors'
import type { WalletBridge, EditProps } from './types'
@ -136,15 +137,23 @@ async function signAndBroadcast({ a, t, deviceId, isCancelled, onSigned, onOpera
}
}
function isRecipientValid(recipient) {
function isRecipientValid(account, recipient) {
try {
bs58check.decode(recipient)
return true
return !(account && account.freshAddress === recipient)
} catch (e) {
return false
}
}
function getRecipientWarning(account, recipient) {
if (account.freshAddress === recipient) {
return new InvalidAddressBecauseDestinationIsAlsoSource()
}
return null
}
function mergeOps(existing: Operation[], newFetched: Operation[]) {
const ids = existing.map(o => o.id)
const all = existing.concat(newFetched.filter(o => !ids.includes(o.id)))
@ -270,7 +279,7 @@ const getServerInfo = (map => endpointConfig => {
})({})
const recipientIsNew = async (endpointConfig, recipient) => {
if (!isRecipientValid(recipient)) return false
if (!isRecipientValid(null, recipient)) return false
const api = apiForEndpointConfig(RippleAPI, endpointConfig)
try {
await api.connect()
@ -505,8 +514,9 @@ const RippleJSBridge: WalletBridge<Transaction> = {
pullMoreOperations: () => Promise.resolve(a => a), // FIXME not implemented
isRecipientValid: (currency, recipient) => Promise.resolve(isRecipientValid(recipient)),
getRecipientWarning: () => Promise.resolve(null),
isRecipientValid: (account, recipient) => Promise.resolve(isRecipientValid(account, recipient)),
getRecipientWarning: (account, recipient) =>
Promise.resolve(getRecipientWarning(account, recipient)),
createTransaction: () => ({
amount: BigNumber(0),

2
src/bridge/makeMockBridge.js

@ -128,7 +128,7 @@ function makeMockBridge(opts?: Opts): WalletBridge<*> {
}
},
isRecipientValid: (currency, recipient) => Promise.resolve(recipient.length > 0),
isRecipientValid: (account, recipient) => Promise.resolve(recipient.length > 0),
getRecipientWarning: () => Promise.resolve(null),
createTransaction: () => ({

4
src/bridge/types.js

@ -52,8 +52,8 @@ export interface WalletBridge<Transaction> {
// count is user's desired number of ops to pull (but implementation can decide to ignore it or not)
pullMoreOperations(initialAccount: Account, count: number): Promise<(Account) => Account>;
isRecipientValid(currency: Currency, recipient: string): Promise<boolean>;
getRecipientWarning(currency: Currency, recipient: string): Promise<?Error>;
isRecipientValid(account: Account, recipient: string): Promise<boolean>;
getRecipientWarning(account: Account, recipient: string): Promise<?Error>;
// Related to send funds:

BIN
src/commands/.DS_Store

Binary file not shown.

84
src/components/ManagerPage/AppsList.js

@ -40,15 +40,35 @@ const mapStateToProps = state => ({
const List = styled(Box).attrs({
horizontal: true,
m: -3,
})`
flex-wrap: wrap;
> * {
width: calc(50% - 10px);
margin-bottom: 20px;
&:nth-child(even) {
margin-left: 20px;
}
@media (max-width: 1000px) {
width: 100%;
&:nth-child(even) {
margin-left: 0;
}
}
}
`
const ICONS_FALLBACK = {
bitcoin_testnet: 'bitcoin',
}
const CATALOG_INFO_ICON = (
<Box color="grey">
<IconInfoCircle size={12} />
</Box>
)
type Status = 'loading' | 'idle' | 'busy' | 'success' | 'error'
type Mode = 'home' | 'installing' | 'uninstalling'
@ -80,6 +100,20 @@ const LoadingApp = () => (
const loadingApp = <LoadingApp />
const FAKE_LIST = (
<List>
{loadingApp}
{loadingApp}
{loadingApp}
{loadingApp}
{loadingApp}
{loadingApp}
{loadingApp}
{loadingApp}
{loadingApp}
</List>
)
class AppsList extends PureComponent<Props, State> {
state = {
status: 'loading',
@ -272,22 +306,16 @@ class AppsList extends PureComponent<Props, State> {
)}
</AppSearchBar>
{this.renderModal()}
{!appsLoaded && (
<Fragment>
<Space of={30} />
<List>
{loadingApp}
{loadingApp}
{loadingApp}
{loadingApp}
{loadingApp}
{loadingApp}
{loadingApp}
{loadingApp}
{loadingApp}
</List>
</Fragment>
)}
{!appsLoaded && FAKE_LIST}
</Box>
)
}
renderTooltip = () => {
const { t } = this.props
return (
<Box ff="Open Sans|SemiBold" fontSize={2}>
{t('manager.apps.help')}
</Box>
)
}
@ -296,24 +324,12 @@ class AppsList extends PureComponent<Props, State> {
const { t } = this.props
return (
<Box flow={6}>
<Box>
<Box mb={4} color="dark" ff="Museo Sans" fontSize={5} flow={2} horizontal align="center">
<span style={{ lineHeight: 1 }}>{t('manager.apps.all')}</span>
<Tooltip
render={() => (
<Box ff="Open Sans|SemiBold" fontSize={2}>
{t('manager.apps.help')}
</Box>
)}
>
<Box color="grey">
<IconInfoCircle size={12} />
</Box>
</Tooltip>
</Box>
{this.renderList()}
<Box>
<Box mb={4} color="dark" ff="Museo Sans" fontSize={5} flow={2} horizontal align="center">
<span>{t('manager.apps.all')}</span>
<Tooltip render={this.renderTooltip}>{CATALOG_INFO_ICON}</Tooltip>
</Box>
{this.renderList()}
</Box>
)
}

3
src/components/ManagerPage/ManagerApp.js

@ -14,15 +14,12 @@ import Button from 'components/base/Button'
export const Container = styled(Box).attrs({
horizontal: true,
my: 2,
mx: 3,
p: 4,
bg: 'white',
boxShadow: p => (p.noShadow ? -1 : 0),
borderRadius: 4,
flow: 2,
})`
width: calc(50% - 30px);
line-height: normal;
`

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

@ -31,6 +31,8 @@ export function GenuineCheckUnavailableFooter({
</Button>
<Box horizontal ml="auto">
<Button
outline
outlineColor="alertRed"
disabled={false}
event="Onboarding Skip Genuine Check"
onClick={() => nextStep()}
@ -38,9 +40,6 @@ export function GenuineCheckUnavailableFooter({
>
{t('common.skipThisStep')}
</Button>
<Button onClick={nextStep} disabled primary>
{t('common.continue')}
</Button>
</Box>
</OnboardingFooterWrapper>
)

2
src/components/SelectExchange.js

@ -87,7 +87,7 @@ class SelectExchange extends Component<
this.setState({ exchanges, isLoading: false })
}
} catch (error) {
logger.error(error)
logger.critical(error)
if (!this._unmounted && this._loadId === _loadId) {
this.setState({ error, isLoading: false })
}

14
src/components/SettingsPage/RepairDeviceButton.js

@ -6,6 +6,7 @@ import { connect } from 'react-redux'
import { withRouter } from 'react-router'
import { translate } from 'react-i18next'
import { push } from 'react-router-redux'
import logger from 'logger'
import type { T } from 'types/common'
import firmwareRepair from 'commands/firmwareRepair'
@ -32,27 +33,38 @@ class RepairDeviceButton extends PureComponent<Props, State> {
progress: 0,
}
componentWillUnmount() {
if (this.timeout) {
clearTimeout(this.timeout)
}
}
open = () => this.setState({ opened: true, error: null })
sub: *
timeout: *
close = () => {
if (this.sub) this.sub.unsubscribe()
if (this.timeout) clearTimeout(this.timeout)
this.setState({ opened: false, isLoading: false, error: null, progress: 0 })
}
repair = (version = null) => {
if (this.state.isLoading) return
const { push } = this.props
this.setState({ isLoading: true })
this.timeout = setTimeout(() => this.setState({ isLoading: true }), 500)
this.sub = firmwareRepair.send({ version }).subscribe({
next: patch => {
this.setState(patch)
},
error: error => {
logger.critical(error)
if (this.timeout) clearTimeout(this.timeout)
this.setState({ error, isLoading: false, progress: 0 })
},
complete: () => {
if (this.timeout) clearTimeout(this.timeout)
this.setState({ opened: false, isLoading: false, progress: 0 }, () => {
push('/manager')
})

13
src/components/SettingsPage/sections/Export.js

@ -69,7 +69,10 @@ class SectionExport extends PureComponent<Props, State> {
<Text ff="Open Sans|SemiBold" color="dark">
{'+'}
</Text>
{'button in Accounts'}
{'button in'}
<Text ff="Open Sans|SemiBold" color="dark">
{'Accounts'}
</Text>
</Trans>
</Box>
),
@ -93,7 +96,13 @@ class SectionExport extends PureComponent<Props, State> {
icon: <BulletRowIcon>{'3'}</BulletRowIcon>,
desc: (
<Box style={{ display: 'block' }}>
<Trans i18nKey="settings.export.modal.step3" />
<Trans i18nKey="settings.export.modal.step3">
{'Scan the'}
<Text ff="Open Sans|SemiBold" color="dark">
{'LiveQR Code'}
</Text>
{'until the loader hits 100%'}
</Trans>
</Box>
),
},

4
src/components/modals/AddAccounts/index.js

@ -24,6 +24,7 @@ import { closeModal } from 'reducers/modals'
import Modal from 'components/base/Modal'
import Stepper from 'components/base/Stepper'
import { validateNameEdition } from '@ledgerhq/live-common/lib/account'
import logger from 'logger'
import StepChooseCurrency, { StepChooseCurrencyFooter } from './steps/01-step-choose-currency'
import StepConnectDevice, { StepConnectDeviceFooter } from './steps/02-step-connect-device'
@ -166,6 +167,9 @@ class AddAccounts extends PureComponent<Props, State> {
handleSetCurrency = (currency: ?Currency) => this.setState({ currency })
handleSetScanStatus = (scanStatus: string, err: ?Error = null) => {
if (err) {
logger.critical(err)
}
this.setState({ scanStatus, err })
}

4
src/components/modals/Receive/index.js

@ -8,6 +8,7 @@ import { createStructuredSelector } from 'reselect'
import SyncSkipUnderPriority from 'components/SyncSkipUnderPriority'
import logger from 'logger'
import Track from 'analytics/Track'
import type { Account } from '@ledgerhq/live-common/lib/types'
@ -141,6 +142,9 @@ class ReceiveModal extends PureComponent<Props, State> {
handleChangeAppOpened = (isAppOpened: boolean) => this.setState({ isAppOpened })
handleChangeAddressVerified = (isAddressVerified: boolean, err: ?Error) => {
if (err && err.name !== 'UserRefusedAddress') {
logger.critical(err)
}
this.setState({ isAddressVerified, verifyAddressError: err })
}

10
src/components/modals/Send/fields/RecipientField.js

@ -53,8 +53,8 @@ class RecipientField<Transaction> extends Component<
const { account, bridge, transaction } = this.props
const syncId = ++this.syncId
const recipient = bridge.getTransactionRecipient(account, transaction)
const isValid = await bridge.isRecipientValid(account.currency, recipient)
const warning = await bridge.getRecipientWarning(account.currency, recipient)
const isValid = await bridge.isRecipientValid(account, recipient)
const warning = await bridge.getRecipientWarning(account, recipient)
if (syncId !== this.syncId) return
if (this.isUnmounted) return
this.setState({ isValid, warning })
@ -69,9 +69,7 @@ class RecipientField<Transaction> extends Component<
if (amount) {
t = bridge.editTransactionAmount(account, t, amount)
}
const warning = fromQRCode
? await bridge.getRecipientWarning(account.currency, recipient)
: null
const warning = fromQRCode ? await bridge.getRecipientWarning(account, recipient) : null
if (this.isUnmounted) return false
if (warning) {
// clear the input if field has warning AND has a warning
@ -97,7 +95,7 @@ class RecipientField<Transaction> extends Component<
const error =
!value || isValid
? QRCodeRefusedReason
: new InvalidAddress(null, { currencyName: account.currency.name })
: warning || new InvalidAddress(null, { currencyName: account.currency.name })
return (
<Box flow={1}>

4
src/components/modals/Send/index.js

@ -12,6 +12,7 @@ import Track from 'analytics/Track'
import { updateAccountWithUpdater } from 'actions/accounts'
import { MODAL_SEND } from 'config/constants'
import { getBridgeForCurrency } from 'bridge'
import logger from 'logger'
import type { WalletBridge } from 'bridge/types'
import type { T, Device } from 'types/common'
@ -180,6 +181,9 @@ class SendModal extends PureComponent<Props, State<*>> {
}
handleTransactionError = (error: Error) => {
if (!(error instanceof UserRefusedOnDevice)) {
logger.critical(error)
}
const stepVerificationIndex = this.STEPS.findIndex(step => step.id === 'verification')
if (stepVerificationIndex === -1) return
this.setState({ error })

2
src/components/modals/Send/steps/01-step-amount.js

@ -133,7 +133,7 @@ export class StepAmountFooter extends PureComponent<
const totalSpent = await bridge.getTotalSpent(account, transaction)
if (syncId !== this.syncId) return
const isRecipientValid = await bridge.isRecipientValid(
account.currency,
account,
bridge.getTransactionRecipient(account, transaction),
)
if (syncId !== this.syncId) return

6
src/components/modals/UpdateFirmware/index.js

@ -11,6 +11,7 @@ import type { FirmwareUpdateContext } from '@ledgerhq/live-common/lib/types/mana
import type { StepProps as DefaultStepProps, Step } from 'components/base/Stepper'
import type { ModalStatus } from 'components/ManagerPage/FirmwareUpdate'
import logger from 'logger'
import { FreezeDeviceChangeEvents } from '../../ManagerPage/HookDeviceChange'
import StepFullFirmwareInstall from './steps/01-step-install-full-firmware'
@ -82,7 +83,10 @@ class UpdateModal extends PureComponent<Props, State> {
t: this.props.t,
})
setError = (e: Error) => this.setState({ error: e })
setError = (e: Error) => {
logger.critical(e)
this.setState({ error: e })
}
handleReset = () => this.setState({ stepId: 'idCheck', error: null, nonce: this.state.nonce++ })

13
static/i18n/en/app.json

@ -366,10 +366,10 @@
"modal": {
"button": "Done",
"title": "Scan to export to mobile",
"listTitle": "To import accounts on your Ledger Live Mobile app:",
"step1": "Tap the <1><0>+</0></1> button in Accounts",
"listTitle": "On the Ledger Live mobile app:",
"step1": "Tap the <1><0>+</0></1> button in <3><0>Accounts</0></3>",
"step2": "Tap <1><0>Import desktop accounts</0></1>",
"step3": "Scan until the loader hits 100%"
"step3": "Scan the <1><0>LiveQR code</0></1> until the loader hits 100%"
}
},
"display": {
@ -783,7 +783,7 @@
"description": "Please retry. Interacting with Ledger's API server went wrong."
},
"LedgerAPIErrorWithMessage": {
"title": "Oops, {{message}}",
"title": "{{message}}",
"description": "Please retry or contact Ledger Support"
},
"LedgerAPINotAvailable": {
@ -900,6 +900,9 @@
"InvalidAddress": {
"title": "This is not a valid {{currencyName}} address"
},
"InvalidAddressBecauseDestinationIsAlsoSource": {
"title": "Recipient address is the same as the sender address"
},
"CantOpenDevice": {
"title": "Oops, couldn’t connect to device",
"description": "Device detected but connection failed. Please try again or contact us if the problem persists."
@ -919,4 +922,4 @@
"description": "Please contact Ledger Support"
}
}
}
}

90
yarn.lock

@ -1677,56 +1677,48 @@
camelcase "^5.0.0"
prettier "^1.13.7"
"@ledgerhq/errors@^4.32.0":
version "4.33.7"
resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-4.33.7.tgz#b78becd20e8a68f7115ad0986fa357a8adddf6b7"
integrity sha512-1vKWcttI5NHpT6rMKKuxWPAjfwDgfgUTf/AyNAT5KXHlhiLvqnA3NDCdNUVadajVNKSa/s1u1ZWKismtbfePzg==
"@ledgerhq/errors@^4.32.0", "@ledgerhq/errors@^4.35.1":
version "4.35.1"
resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-4.35.1.tgz#3f162dc05480e444083b6381bd098df187751633"
integrity sha512-2Bo3/NRKyz3ddR07TvZ87VpDJc8fz4+ONLJnhzC0mwIwu+Pxal6SgCBiGtv503oGxkgDuG5PtODZBaehWkGRnQ==
"@ledgerhq/hw-app-btc@^4.32.0":
version "4.32.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-btc/-/hw-app-btc-4.32.0.tgz#e883dcaa3ebb4aca1e2cb27acfc47b8db4e85f3f"
integrity sha512-N/RxtkPVjTDwU+lDPQQE7+4YQMXaXStDrpufQbDn0NXoaJ8KgY+QGkOH6bkuwV+LQvc7rEaM7E3p7/t58KJpMg==
"@ledgerhq/hw-app-btc@^4.32.0", "@ledgerhq/hw-app-btc@^4.35.0":
version "4.35.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-btc/-/hw-app-btc-4.35.0.tgz#aafd655c988da39f774b0a4706e7f8897222f414"
integrity sha512-oX9YcQAuU+rOJm/lE7YF5+JXNppHcUv23ZltGz5CbWHnhm7Tqo4MOR8N5oSnHKlHW+IawfWCPN5PqdF7RGyQ5w==
dependencies:
"@ledgerhq/hw-transport" "^4.32.0"
"@ledgerhq/hw-transport" "^4.35.0"
create-hash "^1.1.3"
"@ledgerhq/hw-app-btc@^4.34.0":
version "4.34.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-btc/-/hw-app-btc-4.34.0.tgz#0bbc46afd29de04ac6a73582fbf9a09fcf5ed117"
integrity sha512-xR4rH8o8YRvyhnTvb8g89NAJQQqXJkApiFtCvduBamu5V+rDvhHYlFu2B+CU6g8lzLFACMDIqJqXbmwT80AGjw==
"@ledgerhq/hw-app-eth@^4.32.0", "@ledgerhq/hw-app-eth@^4.35.0":
version "4.35.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-4.35.0.tgz#3a8c1b0db87224a24ff5441a0e819122e5585f2d"
integrity sha512-MSDr8+CaoXhtm64ELuI/8wpcfmrMUjzGJgASY6bnjc82vAW+6sHNZlTU0zWRTZxqQUuZ8WpuJP159cf92MWq3g==
dependencies:
"@ledgerhq/hw-transport" "^4.32.0"
create-hash "^1.1.3"
"@ledgerhq/hw-transport" "^4.35.0"
"@ledgerhq/hw-app-eth@^4.32.0":
version "4.32.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-4.32.0.tgz#7d43ca2c7952f1fb726e02c3b4485be10af481a2"
integrity sha512-d22WinjcsqJNoZSI+6UpTWZ7hl+UhL2dFeVeliCwtBWSj40z6F25MpoviGxPsv0WC7IUjayw+a9jIRcOJ5kkIw==
"@ledgerhq/hw-app-xrp@^4.32.0", "@ledgerhq/hw-app-xrp@^4.35.0":
version "4.35.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-xrp/-/hw-app-xrp-4.35.0.tgz#f6aec06ae53f8732d90f745963a2de96c2ffa432"
integrity sha512-kQLdr9xrYvkFR9+QVyTNtmSGFDfrQ63ac0QhWKEoILiiQ0dxfZ7qCCp/qPJk/sx9H8dMX37X6y+xAnSU1frbfg==
dependencies:
"@ledgerhq/hw-transport" "^4.32.0"
"@ledgerhq/hw-app-xrp@^4.32.0":
version "4.32.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-xrp/-/hw-app-xrp-4.32.0.tgz#260daafa9de1073598ea91ddfeb168dc437edd50"
integrity sha512-MNmLAGUp7Bnj/mjg1Lo5bK1v+q/QPYw7RJAbI4Vl1A4Fsqj6oiZspnSK+BTHGp+CRJavCwumjKuf5y3X5Dp8cA==
dependencies:
"@ledgerhq/hw-transport" "^4.32.0"
"@ledgerhq/hw-transport" "^4.35.0"
bip32-path "0.4.2"
"@ledgerhq/hw-transport-node-hid@^4.32.0":
version "4.33.3"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-4.33.3.tgz#5e96dca2be0a23d80814303f262398087b208a6a"
integrity sha512-hmNAm7k385RJXY38hVUpzYgGgyk9QjScD3erNlFCTO8FnnxmEJCFUmVhWkv4sTwufuUJSpXL3ZXXNZ44qLMJpg==
"@ledgerhq/hw-transport-node-hid@^4.35.0":
version "4.35.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-4.35.0.tgz#0eba08e5edd14a8c779ebaf73ec21976ee5f112e"
integrity sha512-Otnymk9B7qCEfjych/SvTvJsMM+DqyoB0saEwL80ukjuGFqMunecrG5w8nC4aCc169IVz70Spkg2uU90TBUCuw==
dependencies:
"@ledgerhq/hw-transport" "^4.32.0"
"@ledgerhq/hw-transport" "^4.35.0"
lodash "^4.17.11"
node-hid "^0.7.2"
usb "^1.3.3"
"@ledgerhq/hw-transport@^4.21.0", "@ledgerhq/hw-transport@^4.32.0":
version "4.32.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-4.32.0.tgz#592b9dc51459cb1cd31ce9444cf943f627bc4beb"
integrity sha512-Wgsk9UHC4RShqYoDeIEeKgHZOvNCtB0WWIG0xqlVPzS+IcKDkIxtXQw7hTA7GQSuDuGeauVtlbTQ5yat6+2/BA==
"@ledgerhq/hw-transport@^4.21.0", "@ledgerhq/hw-transport@^4.32.0", "@ledgerhq/hw-transport@^4.35.0":
version "4.35.0"
resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-4.35.0.tgz#aa7b851111ed759cd7489fa07a7b34c1773e8314"
integrity sha512-o8ekdoCkHMvOByIKDmAMNDjm8Q5cu+sbqmebPtGrHAPbgIZBUbNA5UupY/Om+xypdxXYnuBw+MF8FyIVOjnIsg==
dependencies:
events "^3.0.0"
@ -2258,6 +2250,11 @@
text-table "^0.2.0"
webpack-log "^1.1.2"
"@yarnpkg/lockfile@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"
integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==
abab@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e"
@ -5225,6 +5222,11 @@ commander@2.6.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.6.0.tgz#9df7e52fb2a0cb0fb89058ee80c3104225f37e1d"
integrity sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0=
commander@^2.10.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
commander@~2.13.0:
version "2.13.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
@ -13211,12 +13213,7 @@ react-inspector@^2.2.2:
babel-runtime "^6.26.0"
is-dom "^1.0.9"
react-is@^16.3.1, react-is@^16.4.1:
version "16.4.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.4.1.tgz#d624c4650d2c65dbd52c72622bbf389435d9776e"
integrity sha512-xpb0PpALlFWNw/q13A+1aHeyJyLYCg0/cCHPUA43zYluZuIPHaHL3k8OBsTgQtxqW0FhyDEMvi8fZ/+7+r4OSQ==
react-is@^16.3.2:
react-is@^16.3.1, react-is@^16.3.2, react-is@^16.4.1:
version "16.5.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.5.2.tgz#e2a7b7c3f5d48062eb769fcb123505eb928722e3"
integrity sha512-hSl7E6l25GTjNEZATqZIuWOgSnpXb3kD0DVCujmg46K5zLxsbiKaaT6VO9slkSBDPZfYs30lwfJwbOFOnoEnKQ==
@ -17062,6 +17059,15 @@ yargs@~3.10.0:
decamelize "^1.0.0"
window-size "0.1.0"
yarn-deduplicate@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/yarn-deduplicate/-/yarn-deduplicate-1.1.1.tgz#19b4a87654b66f55bf3a4bd6b153b4e4ab1b6e6d"
integrity sha512-2FDJ1dFmtvqhRmfja89ohYzpaheCYg7BFBSyaUq+kxK0y61C9oHv1XaQovCWGJtP2WU8PksQOgzMVV7oQOobzw==
dependencies:
"@yarnpkg/lockfile" "^1.1.0"
commander "^2.10.0"
semver "^5.3.0"
yauzl@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005"

Loading…
Cancel
Save