This repository has been archived by the owner on Mar 28, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 31
Add Trezor wallet connector #206
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
0d36816
Add Trezor wallet connector
liamzebedee b38594d
Add custom Trezor subprovider
liamzebedee bd18333
Add missing trezor-connect package
liamzebedee 9f81151
Import hexToPaddedBuffer from utils
liamzebedee a3c78da
Remove ts types in the trezor.js file
r-czajkowski 9ae4508
Add a defaultAccount field to the TrezorConnector
r-czajkowski f7743bd
Add ChooseAccount component
r-czajkowski be8ef0c
Fix the `activateProvider` fn
r-czajkowski b061f3f
Add commons styles
r-czajkowski 81438cb
Extract components
r-czajkowski 24a229c
Remove unused console.log and variable in web3.js
r-czajkowski da79c34
Pass a number of accounts to the getAccounts fn
r-czajkowski a5f77d6
Catch error while aborting the wallet connection
r-czajkowski 92d57e8
Change hardware wallets icons
r-czajkowski d6e2cfe
Add support for ledger live/legacy
r-czajkowski fb516a1
Cleanup in the ledger_subprovider.js
r-czajkowski d7928e7
Merge branch 'heath-ledger' into tresor-317-integration
ironng 0ea3d33
Update ledger name check
ironng f5d9a04
Address nits
ironng File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,124 +3,197 @@ import Check from '../svgs/Check' | |
import { useWeb3React } from '@web3-react/core' | ||
import { InjectedConnector } from '@web3-react/injected-connector' | ||
import { LedgerConnector } from '../../connectors/ledger' | ||
import { TrezorConnector } from '../../connectors/trezor' | ||
|
||
const ETH_CHAIN_ID = process.env.ETH_CHAIN_ID || 1337 | ||
const ETH_WS_URL = process.env.ETH_WS_URL || 'ws://localhost:8545' | ||
const CHAIN_ID = process.env.CHAIN_ID || 1101 | ||
const ETH_RPC_URL = process.env.ETH_RPC_URL || 'ws://localhost:8546' | ||
|
||
// Connectors. | ||
const injectedConnector = new InjectedConnector({}) | ||
|
||
const ledgerConnector = new LedgerConnector({ | ||
chainId: ETH_CHAIN_ID, | ||
url: ETH_WS_URL | ||
const ledgerLiveConnector = new LedgerConnector({ | ||
chainId: CHAIN_ID, | ||
url: ETH_RPC_URL, | ||
baseDerivationPath: "44'/60'/0'/0", | ||
}) | ||
|
||
const ledgerLegacyConnector = new LedgerConnector({ | ||
chainId: CHAIN_ID, | ||
url: ETH_RPC_URL, | ||
baseDerivationPath: "44'/60'/0'", | ||
}) | ||
|
||
const trezorConnector = new TrezorConnector({ | ||
chainId: CHAIN_ID, | ||
pollingInterval: 1000, | ||
requestTimeoutMs: 1000, | ||
config: { | ||
chainId: CHAIN_ID, | ||
}, | ||
url: ETH_RPC_URL, | ||
manifestEmail: '[email protected]', | ||
manifestAppUrl: 'https://localhost' | ||
}) | ||
|
||
// Wallets. | ||
const WALLETS = [ | ||
{ | ||
name: "Metamask", | ||
icon: "/images/metamask-fox.svg", | ||
showName: true, | ||
connector: injectedConnector | ||
}, | ||
{ | ||
name: "Ledger", | ||
name: "Ledger Legacy", | ||
icon: "/images/ledger.svg", | ||
connector: ledgerConnector | ||
connector: ledgerLegacyConnector, | ||
isHardwareWallet: true, | ||
}, | ||
{ | ||
name: "Ledger Live", | ||
icon: "/images/ledger.svg", | ||
connector: ledgerLiveConnector, | ||
isHardwareWallet: true, | ||
}, | ||
{ | ||
name: "Trezor", | ||
icon: "/images/trezor.svg", | ||
connector: trezorConnector, | ||
isHardwareWallet: true, | ||
} | ||
] | ||
|
||
|
||
export const ConnectWalletDialog = ({ shown, onConnected, onClose }) => { | ||
const { active, account, activate, chainId, connector } = useWeb3React() | ||
const { active, account, activate } = useWeb3React() | ||
|
||
let [chosenWallet, setChosenWallet] = useState(null) | ||
let [chosenWallet, setChosenWallet] = useState({}) | ||
let [error, setError] = useState(null) | ||
let state = { | ||
chosenWallet, | ||
error | ||
} | ||
const [availableAccounts, setAvailableAccounts] = useState([]) | ||
|
||
async function chooseWallet(wallet) { | ||
setChosenWallet(wallet) | ||
try { | ||
setChosenWallet(wallet) | ||
if(wallet.isHardwareWallet) { | ||
await wallet.connector.activate() | ||
setAvailableAccounts(await wallet.connector.getAccounts()) | ||
} else { | ||
await activateProvider(null, wallet) | ||
} | ||
} catch(error) { | ||
setError(error.toString()) | ||
} | ||
} | ||
|
||
const activateProvider = async (selectedAccount, wallet = chosenWallet) => { | ||
try { | ||
if(wallet.isHardwareWallet) { | ||
wallet.connector.setDefaultAccount(selectedAccount) | ||
} | ||
await activate(wallet.connector, undefined, true) | ||
onConnected() | ||
} catch(ex) { | ||
setError(ex.toString()) | ||
throw ex | ||
} | ||
} | ||
|
||
const ChooseWalletStep = () => { | ||
return <> | ||
<div className="title">Connect to a wallet</div> | ||
<p>This wallet will be used to sign transactions on Ethereum.</p> | ||
|
||
<ul className='wallets'> | ||
{ | ||
WALLETS.map(wallet => { | ||
return <li className='wallet-option' onClick={() => chooseWallet(wallet)}> | ||
<img src={wallet.icon} /> | ||
{wallet.showName && wallet.name} | ||
</li> | ||
}) | ||
} | ||
</ul> | ||
</> | ||
const reconnectWallet = async () => { | ||
setError(null) | ||
await chooseWallet(chosenWallet) | ||
} | ||
|
||
const ConnectToWalletStep = () => { | ||
if(error) { | ||
return <ErrorConnecting/> | ||
} | ||
return <div className={`modal connect-wallet ${shown ? 'open' : 'closed'}`}> | ||
<div className="modal-body"> | ||
<div className="close"> | ||
<div className="x" onClick={onClose}>╳</div> | ||
</div> | ||
{!chosenWallet.name && <ChooseWalletStep onChooseWallet={chooseWallet} />} | ||
{(chosenWallet.name && !active) && | ||
<ConnectToWalletStep | ||
wallet={chosenWallet} | ||
error={error}onTryAgainClick={reconnectWallet} | ||
/>} | ||
{(chosenWallet.name && active) && <ConnectedView wallet={chosenWallet} account={account} />} | ||
<ChooseAccount | ||
wallet={chosenWallet} | ||
availableAccounts={availableAccounts} | ||
active={active} | ||
onAccountSelect={activateProvider} | ||
/> | ||
</div> | ||
</div> | ||
} | ||
|
||
if(chosenWallet.name == 'Ledger') { | ||
return <> | ||
<div className="title">Plug In Ledger & Enter Pin</div> | ||
<p>Open Ethereum application and make sure Contract Data and Browser Support are enabled.</p> | ||
<p>Connecting...</p> | ||
</> | ||
} | ||
const ChooseWalletStep = ({ onChooseWallet }) => { | ||
return <> | ||
<div className="title">Connect to a wallet</div> | ||
<p>This wallet will be used to sign transactions on Ethereum.</p> | ||
|
||
return <> | ||
<div className="title">Connect to a wallet</div> | ||
<p>Connecting to {chosenWallet.name} wallet...</p> | ||
</> | ||
<ul className='wallets'> | ||
{ | ||
WALLETS.map(wallet => { | ||
return <li key={wallet.name} className='wallet-option' onClick={() => onChooseWallet(wallet)}> | ||
<img alt="wallet-icon" src={wallet.icon} /> | ||
{wallet.name} | ||
</li> | ||
}) | ||
} | ||
</ul> | ||
</> | ||
} | ||
|
||
const ConnectToWalletStep = ({ error, wallet, onTryAgainClick }) => { | ||
if(error) { | ||
return <ErrorConnecting error={error} wallet={wallet} onTryAgainClick={onTryAgainClick} /> | ||
} | ||
|
||
const ErrorConnecting = () => { | ||
if(wallet.name.includes('Ledger')) { | ||
return <> | ||
<div className="title">Connect to a wallet</div> | ||
<p>Error connecting to {chosenWallet.name} wallet...</p> | ||
<a onClick={async () => { | ||
setError(null) | ||
await chooseWallet(chosenWallet) | ||
}}> | ||
Try Again | ||
</a> | ||
{ error && <p>{error}</p> } | ||
<div className="title">Plug In Ledger & Enter Pin</div> | ||
<p>Open Ethereum application and make sure Contract Data and Browser Support are enabled.</p> | ||
<p>Connecting...</p> | ||
</> | ||
} | ||
|
||
const ConnectedView = () => { | ||
return <div className='connected-view'> | ||
<div className="title">Wallet connected</div> | ||
<div className='details'> | ||
<p>{chosenWallet.name}</p> | ||
<p>Account: {account}</p> | ||
</div> | ||
</div> | ||
} | ||
return <> | ||
<div className="title">Connect to a wallet</div> | ||
<p>Connecting to {wallet.name} wallet...</p> | ||
</> | ||
} | ||
|
||
return <div className={`modal connect-wallet ${shown ? 'open' : 'closed'}`}> | ||
<div className="modal-body"> | ||
<div className="close"> | ||
<div className="x" onClick={onClose}>╳</div> | ||
</div> | ||
{!chosenWallet && <ChooseWalletStep />} | ||
{(chosenWallet && !active) && <ConnectToWalletStep />} | ||
{(chosenWallet && active) && <ConnectedView />} | ||
const ChooseAccount = ({ wallet, availableAccounts, active, onAccountSelect }) => { | ||
if(wallet.isHardwareWallet && availableAccounts.length !== 0 && !active) { | ||
return ( | ||
<> | ||
<div className="title mb-2">Select account</div> | ||
{availableAccounts.map(account => ( | ||
<div key={account} className="cursor-pointer mb-1" onClick={() => onAccountSelect(account)}> | ||
{account} | ||
</div> | ||
))} | ||
</> | ||
) | ||
} | ||
|
||
return null | ||
} | ||
|
||
const ConnectedView = ({ wallet, account }) => { | ||
return <div className='connected-view'> | ||
<div className="title">Wallet connected</div> | ||
<div className='details'> | ||
<p>{wallet.name}</p> | ||
<p>Account: {account}</p> | ||
</div> | ||
</div> | ||
} | ||
|
||
const ErrorConnecting = ({ wallet, error, onTryAgainClick }) => { | ||
return <> | ||
<div className="title">Connect to a wallet</div> | ||
<p>Error connecting to {wallet.name} wallet...</p> | ||
<span onClick={onTryAgainClick}> | ||
Try Again | ||
</span> | ||
{ error && <p>{error}</p> } | ||
</> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spacing and indentation is odd here but we can fix it when we do a pass with prettier