1import React, { useCallback, useEffect } from 'react';
2import cn from 'classnames';
3import { Just, Nothing } from 'folktale/maybe';
13import { times } from 'lodash';
14import * as bip32 from 'bip32';
15import Transport from '@ledgerhq/hw-transport-u2f';
16import Eth from '@ledgerhq/hw-app-eth';
17import * as secp256k1 from 'secp256k1';
19import { useWallet } from 'store/wallet';
21import { ForwardButton } from 'components/Buttons';
27} from 'lib/useInputs';
35import { WALLET_TYPES } from 'lib/wallet';
36import useLoginView from 'lib/useLoginView';
37import useBreakpoints from 'lib/useBreakpoints';
40 { text: 'Ledger Live', value: LEDGER_LIVE_PATH },
41 { text: 'Ledger Legacy', value: LEDGER_LEGACY_PATH },
44const ACCOUNT_OPTIONS = times(20, i => ({
45 text: `Account #${i + 1}`,
49export default function Ledger({ className }) {
50 useLoginView(WALLET_TYPES.LEDGER);
52 const { setWallet, setWalletHdPath } = useWallet();
54 // derivation path input
55 const [derivationPathInput, { data: basePathPattern }] = useSelectInput({
56 name: 'derivationpath',
57 label: 'Derivation Path',
58 placeholder: 'Choose path pattern...',
59 options: PATH_OPTIONS,
63 const [accountInput, { data: accountIndex }] = useSelectInput({
66 placeholder: 'Choose account...',
67 options: ACCOUNT_OPTIONS,
71 const [customPathInput, { data: useCustomPath }] = useCheckboxInput({
73 label: 'Custom HD Path',
82 { setValue: setHdPath },
86 initialValue: basePathPattern.replace(/x/g, 0),
89 const pollDevice = useCallback(async () => {
90 const transport = await Transport.create();
91 const eth = new Eth(transport);
92 const path = chopHdPrefix(hdPath);
95 const info = await eth.getAddress(path, false, true);
96 const publicKey = Buffer.from(info.publicKey, 'hex');
97 const chainCode = Buffer.from(info.chainCode, 'hex');
98 const pub = secp256k1.publicKeyConvert(publicKey, true);
99 const hd = bip32.fromPublicKey(pub, chainCode);
101 setWalletHdPath(addHdPrefix(hdPath));
103 console.error(error);
104 setWallet(Nothing());
106 }, [hdPath, setWallet, setWalletHdPath]);
108 // when the base path pattern or the account index changes
109 // update the hd path in our input
112 // updated by useForm
114 setHdPath(basePathPattern.replace(/x/g, accountIndex));
116 }, [useCustomPath, setHdPath, basePathPattern, accountIndex]);
118 const full = useBreakpoints([true, true, false]);
119 const half = useBreakpoints([false, false, true]);
120 const isHTTPS = document.location.protocol === 'https:';
122 // when not on https, tell user how to get there
123 const renderHTTP = () => (
125 <Grid.Item full as={H5}>
129 <Grid.Item full as={P}>
130 To authenticate and sign transactions with a Ledger, Bridge must be
131 serving over HTTPS on localhost. You can do this via the following:
134 <Grid.Item full as="ol">
139 href="https://github.com/FiloSottile/mkcert"
140 rel="noopener noreferrer">
145 Install a local certificate authority via <code>mkcert -install</code>
148 In your <code>bridge</code> directory, generate a certificate valid
149 for localhost via <code>mkcert localhost</code>. This will produce two
150 files: <code>localhost.pem</code>, the local certificate, and
151 <code>localhost-key.pem</code> , its corresponding private key.
154 Run <code>python bridge-https.py</code>
156 <li className="mt3">Return to this page.</li>
161 const renderHTTPS = () => (
163 <Grid.Item full as={H5}>
164 Authenticate With Your Ledger
166 <Grid.Item full as={Text} className="f6 mb3">
167 Connect and authenticate to your Ledger, and then open the "Ethereum"
168 application. If you're running on older firmware, make sure the "browser
169 support" option is turned on. To sign transactions, you'll also need to
170 enable the "contract data" option.
173 {useCustomPath && <Grid.Item full as={Input} {...hdPathInput} />}
181 className={cn({ pr1: half })}
182 {...derivationPathInput}
188 className={cn({ pl1: half })}
194 <Grid.Item full as={CheckboxInput} className="mv3" {...customPathInput} />
201 onClick={pollDevice}>
208 <Grid className={className}>{isHTTPS ? renderHTTPS() : renderHTTP()}</Grid>
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list