Skip to content

Commit

Permalink
Add dropdown for ledger transport
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidTranDucVL committed Jun 8, 2021
1 parent bca4044 commit bc876ce
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 50 deletions.
14 changes: 9 additions & 5 deletions app/frontend/actions/wallet.ts
Expand Up @@ -8,7 +8,7 @@ import debugLog from '../helpers/debugLog'
import getConversionRates from '../helpers/getConversionRates'

import {ADALITE_CONFIG} from '../config'
import {AccountInfo, Lovelace, AssetFamily, AuthMethodType} from '../types'
import {AccountInfo, Lovelace, AssetFamily, AuthMethodType, LedgerTransportType} from '../types'
import {initialState} from '../store'
import {State, Store} from '../state'
import errorActions from './error'
Expand Down Expand Up @@ -60,27 +60,31 @@ export default (store: Store) => {
{
cryptoProviderType,
walletSecretDef,
forceWebUsb,
ledgerTransportType,
shouldExportPubKeyBulk,
}: {
cryptoProviderType: CryptoProviderType
walletSecretDef?: any // TODO: until now, arguments came in freestyle combinations, refactor
forceWebUsb?: boolean // into strict combinations and types
ledgerTransportType?: LedgerTransportType
shouldExportPubKeyBulk: boolean
}
) => {
loadingAction(state, 'Loading wallet data...')
setState({walletLoadingError: undefined})
const isShelleyCompatible = !(walletSecretDef && walletSecretDef.derivationScheme.type === 'v1')
const config = {...ADALITE_CONFIG, isShelleyCompatible, shouldExportPubKeyBulk}
const config = {
...ADALITE_CONFIG,
isShelleyCompatible,
shouldExportPubKeyBulk,
ledgerTransportType,
}
try {
const cryptoProvider = await ShelleyCryptoProviderFactory.getCryptoProvider(
cryptoProviderType,
{
walletSecretDef,
network: NETWORKS[ADALITE_CONFIG.ADALITE_NETWORK],
config,
forceWebUsb, // TODO: into config
}
)

Expand Down
3 changes: 3 additions & 0 deletions app/frontend/components/pages/login/hardwareAuth.module.scss
@@ -0,0 +1,3 @@
.ledgerButton {
margin-top: 8px !important;
}
59 changes: 26 additions & 33 deletions app/frontend/components/pages/login/hardwareAuth.tsx
Expand Up @@ -8,12 +8,16 @@ import actions from '../../../actions'
import {useState, useCallback} from 'preact/hooks'
import {localStorageVars} from '../../../localStorage'
import {isMobileOnly} from 'react-device-detect'
import LedgerTransportationSelect from './ledgerTransportationSelect'
import {LedgerTransportType} from '../../../../frontend/types'
import styles from './hardwareAuth.module.scss'

const LoadByHardwareWalletSection = () => {
const {loadWallet} = useActions(actions)
const [enableBulkExport, setBulkExport] = useState(
window.localStorage.getItem(localStorageVars.BULK_EXPORT) !== 'true'
)
const [ledgerTransportType, setLedgerTransportType] = useState(LedgerTransportType.DEFAULT)
const toggleBulkExport = useCallback(() => {
window.localStorage.setItem(localStorageVars.BULK_EXPORT, `${enableBulkExport}`)
setBulkExport(!enableBulkExport)
Expand Down Expand Up @@ -80,40 +84,29 @@ const LoadByHardwareWalletSection = () => {
<div className="authentication-paragraph small">
{LedgerAffiliateLink('Support us by buying one')}
</div>
<button
{...tooltip(
'Support for Ledger is temporarily disabled',
!ADALITE_CONFIG.ADALITE_ENABLE_LEDGER
)}
disabled={!ADALITE_CONFIG.ADALITE_ENABLE_LEDGER}
className="button primary ledger thin-data-balloon"
onClick={() =>
loadWallet({
cryptoProviderType: CryptoProviderType.LEDGER,
shouldExportPubKeyBulk: enableBulkExport,
})
}
>
Unlock with
<div className="ledger-logo-container">
<LedgerLogoWhite />
</div>
</button>
<div className="authentication-paragraph small">
alternatively, if the above does not work:
<div>
<LedgerTransportationSelect onSelect={setLedgerTransportType} />
<button
{...tooltip(
'Support for Ledger is temporarily disabled',
!ADALITE_CONFIG.ADALITE_ENABLE_LEDGER
)}
disabled={!ADALITE_CONFIG.ADALITE_ENABLE_LEDGER}
className={`button primary ledger thin-data-balloon ${styles.ledgerButton}`}
onClick={() =>
loadWallet({
cryptoProviderType: CryptoProviderType.LEDGER,
shouldExportPubKeyBulk: enableBulkExport,
ledgerTransportType,
})
}
>
Unlock with
<div className="ledger-logo-container">
<LedgerLogoWhite />
</div>
</button>
</div>
<button
className="button secondary ledger-webusb"
onClick={() =>
loadWallet({
cryptoProviderType: CryptoProviderType.LEDGER,
forceWebUsb: true,
shouldExportPubKeyBulk: enableBulkExport,
})
}
>
Connect with WebUSB
</button>
</div>
</div>
<div className="authentication-hw-bulk-public-export">
Expand Down
@@ -0,0 +1,7 @@
.dropdown {
margin-top: 16px;
}

.label {
width: 5.5em;
}
36 changes: 36 additions & 0 deletions app/frontend/components/pages/login/ledgerTransportationSelect.tsx
@@ -0,0 +1,36 @@
import {h} from 'preact'
import SearchableSelect from '../../common/searchableSelect'
import {LedgerTransportType} from '../../../../frontend/types'
import styles from './ledgerTransportationSelect.module.scss'

interface Props {
onSelect: (ledgerTransportType: LedgerTransportType) => void
}

const LedgerTransportationSelect = ({onSelect}: Props) => {
const dropdownAssetItems = [
LedgerTransportType.DEFAULT,
LedgerTransportType.U2F,
LedgerTransportType.WEB_USB,
LedgerTransportType.WEB_HID,
]

const displayItem = (item: LedgerTransportType) => <div>{item}</div>

return (
<SearchableSelect
label="Transport"
labelClassName={styles.label}
wrapperClassName="no-margin"
defaultItem={LedgerTransportType.DEFAULT}
displaySelectedItem={displayItem}
displaySelectedItemClassName={`input dropdown ${styles.dropdown}`}
items={dropdownAssetItems}
displayItem={displayItem}
onSelect={onSelect}
showSearch={false}
/>
)
}

export default LedgerTransportationSelect
7 changes: 7 additions & 0 deletions app/frontend/types.ts
Expand Up @@ -106,6 +106,13 @@ export enum AuthMethodType {
KEY_FILE = 'file',
}

export enum LedgerTransportType {
DEFAULT = 'Default',
U2F = 'U2F',
WEB_USB = 'WebUSB',
WEB_HID = 'WebHID',
}

export enum ScreenType {
MOBILE,
TABLET,
Expand Down
33 changes: 21 additions & 12 deletions app/frontend/wallet/shelley/shelley-ledger-crypto-provider.ts
Expand Up @@ -36,6 +36,7 @@ import {
CertificateType,
TokenBundle,
Address,
LedgerTransportType,
} from '../../types'
import {
Network,
Expand Down Expand Up @@ -76,7 +77,7 @@ const isWebHidSupported = async (): Promise<boolean> => {
}

let _activeTransport: Transport | null = null
const getLedgerTransport = async (forceWebUsb: boolean): Promise<Transport> => {
const getLedgerTransport = async (ledgerTransportType: LedgerTransportType): Promise<Transport> => {
if (_activeTransport != null) {
/*
* this is needed for WebHID transport where .create() is not idempotent
Expand All @@ -93,14 +94,24 @@ const getLedgerTransport = async (forceWebUsb: boolean): Promise<Transport> => {
const supportWebHid = await isWebHidSupported()
const supportWebUsb = await isWebUsbSupported()

if (forceWebUsb) {
_activeTransport = await LedgerTransportWebUsb.create()
} else if (supportWebHid) {
_activeTransport = await LedgerTransportWebHid.create()
} else if (supportWebUsb) {
_activeTransport = await LedgerTransportWebUsb.create()
} else {
_activeTransport = await LedgerTransportU2F.create()
switch (ledgerTransportType) {
case LedgerTransportType.WEB_HID:
_activeTransport = await LedgerTransportWebHid.create()
break
case LedgerTransportType.U2F:
_activeTransport = await LedgerTransportU2F.create()
break
case LedgerTransportType.WEB_USB:
_activeTransport = await LedgerTransportWebUsb.create()
break
default:
if (supportWebHid) {
_activeTransport = await LedgerTransportWebHid.create()
} else if (supportWebUsb) {
_activeTransport = await LedgerTransportWebUsb.create()
} else {
_activeTransport = await LedgerTransportU2F.create()
}
}

return _activeTransport
Expand All @@ -109,15 +120,13 @@ const getLedgerTransport = async (forceWebUsb: boolean): Promise<Transport> => {
type CryptoProviderParams = {
network: Network
config: any
forceWebUsb: boolean
}

const ShelleyLedgerCryptoProvider = async ({
network,
config,
forceWebUsb,
}: CryptoProviderParams): Promise<CryptoProvider> => {
const transport = await getLedgerTransport(forceWebUsb)
const transport = await getLedgerTransport(config.ledgerTransportType)
transport.setExchangeTimeout(config.ADALITE_LOGOUT_AFTER * 1000)
const ledger = new Ledger(transport)
const derivationScheme = derivationSchemes.v2
Expand Down

0 comments on commit bc876ce

Please sign in to comment.