From 99e95e8ad8f61289f641c7f5c8436e2d71ead302 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Mon, 24 Aug 2020 17:27:42 +0200 Subject: [PATCH 1/4] Fix typo LEDGER_LEEGACY -> LEDGER_LEGACY Because of this typo, the user was not able to select a ledger legacy accounts path. --- solidity/dashboard/src/components/LedgerModal.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solidity/dashboard/src/components/LedgerModal.jsx b/solidity/dashboard/src/components/LedgerModal.jsx index 02efb97495..1c4f98e79f 100644 --- a/solidity/dashboard/src/components/LedgerModal.jsx +++ b/solidity/dashboard/src/components/LedgerModal.jsx @@ -11,7 +11,7 @@ const LedgerModal = ({ connector, connectAppWithWallet, closeModal }) => { const showMessage = useShowMessage() useEffect(() => { - if (ledgerVersion === "LEDGER_LIVE" || ledgerVersion === "LEDGER_LEEGACY") { + if (ledgerVersion === "LEDGER_LIVE" || ledgerVersion === "LEDGER_LEGACY") { connector[ledgerVersion] .getAccounts() .then(setAccounts) From 172acdb620fe334abd81b16667f0a05e2fb0715c Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Mon, 31 Aug 2020 15:31:24 +0200 Subject: [PATCH 2/4] Fix ledger live derivation path pattern For ledger live derivation path pattern is `m/44'/60'/x'/0/0`, where `x` means index of account. The default implementation of `LedgerSubprovider` doesn't support ledger live derivation path and insted of replacing account index in the place of `x`, increments the latest value. Here we added the right support for ledger live account path and set the account index according to the BIP44. --- solidity/dashboard/src/connectors/ledger.js | 52 +++++++++++++++++---- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/solidity/dashboard/src/connectors/ledger.js b/solidity/dashboard/src/connectors/ledger.js index f50da05b69..1428450854 100644 --- a/solidity/dashboard/src/connectors/ledger.js +++ b/solidity/dashboard/src/connectors/ledger.js @@ -7,8 +7,8 @@ import web3Utils from "web3-utils" import { getBufferFromHex } from "../utils/general.utils" export const LEDGER_DERIVATION_PATHS = { - LEDGER_LIVE: "44'/60'/0'/0", - LEDGER_LEGACY: `44'/60'/0'`, + LEDGER_LIVE: `m/44'/60'/x'/0/0`, + LEDGER_LEGACY: `m/44'/60'/0'/x`, } export class LedgerProvider extends AbstractHardwareWalletConnector { @@ -28,6 +28,8 @@ const ledgerEthereumClientFactoryAsync = async () => { class CustomLedgerSubprovider extends LedgerSubprovider { chainId + addressToPathMap = {} + pathToAddressMap = {} constructor(chainId, baseDerivationPath) { super({ @@ -45,12 +47,9 @@ class CustomLedgerSubprovider extends LedgerSubprovider { } txData.chainId = this.chainId - const initialDerivedKeyInfo = await this._initialDerivedKeyInfoAsync() - const derivedKeyInfo = this._findDerivedKeyInfoForAddress( - initialDerivedKeyInfo, - txData.from - ) - const fullDerivationPath = derivedKeyInfo.derivationPath + const fullDerivationPath = this.addressToPathMap[ + web3Utils.toChecksumAddress(txData.from) + ] try { this._ledgerClientIfExists = await this._createLedgerClientAsync() @@ -92,4 +91,41 @@ class CustomLedgerSubprovider extends LedgerSubprovider { throw error } } + + async getAccountsAsync(numberOfAccounts, accountsOffSet = 0) { + const addresses = [] + for ( + let index = accountsOffSet; + index < numberOfAccounts + accountsOffSet; + index++ + ) { + const address = await this.getAddress(index) + addresses.push(address) + } + + return addresses + } + + async getAddress(index) { + const path = this._baseDerivationPath.replace("x", index) + + let ledgerResponse + try { + this._ledgerClientIfExists = await this._createLedgerClientAsync() + ledgerResponse = await this._ledgerClientIfExists.getAddress( + path, + this._shouldAlwaysAskForConfirmation, + true + ) + } finally { + await this._destroyLedgerClientAsync() + } + + const address = web3Utils.toChecksumAddress(ledgerResponse.address) + + this.addressToPathMap[address] = path + this.pathToAddressMap[path] = address + + return address + } } From c6f37b1b8023a64bc66392855d53848098b58ecb Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Mon, 31 Aug 2020 16:05:02 +0200 Subject: [PATCH 3/4] Add accounts pagination for Ledger accounts Fetching 5 accounts per page. --- .../src/components/ChooseWalletAddress.jsx | 27 +++++++++++- .../dashboard/src/components/LedgerModal.jsx | 42 +++++++++++++++---- .../src/connectors/abstract-connector.js | 10 ++++- .../src/css/choose-wallet-address.less | 23 +++++++++- 4 files changed, 90 insertions(+), 12 deletions(-) diff --git a/solidity/dashboard/src/components/ChooseWalletAddress.jsx b/solidity/dashboard/src/components/ChooseWalletAddress.jsx index 2f58565913..6ac2d1519c 100644 --- a/solidity/dashboard/src/components/ChooseWalletAddress.jsx +++ b/solidity/dashboard/src/components/ChooseWalletAddress.jsx @@ -3,7 +3,14 @@ import Button from "./Button" import { shortenAddress } from "../utils/general.utils" import { ViewAddressInBlockExplorer } from "./ViewInBlockExplorer" -const ChooseWalletAddress = ({ addresses, onSelectAccount }) => { +const ChooseWalletAddress = ({ + addresses, + onSelectAccount, + withPagination, + renderPrevBtn, + onNext, + onPrev, +}) => { const [selectedAccount, setAccount] = useState("") useEffect(() => { @@ -30,6 +37,24 @@ const ChooseWalletAddress = ({ addresses, onSelectAccount }) => { ))} + {withPagination && ( +
+ {renderPrevBtn && ( + + prev + + )} + + next + +
+ )} - {!isEmptyArray(accounts) && ( - + {isFetching ? ( + + ) : ( + !isEmptyArray(accounts) && ( + 0} + onNext={() => setAccountsOffSet((prevOffset) => prevOffset + 5)} + onPrev={() => setAccountsOffSet((prevOffset) => prevOffset - 5)} + /> + ) )} ) diff --git a/solidity/dashboard/src/connectors/abstract-connector.js b/solidity/dashboard/src/connectors/abstract-connector.js index 31729c22e6..f6f156a46a 100644 --- a/solidity/dashboard/src/connectors/abstract-connector.js +++ b/solidity/dashboard/src/connectors/abstract-connector.js @@ -25,8 +25,14 @@ export class AbstractHardwareWalletConnector extends Web3ProviderEngine { return await this.getAccount() } - getAccounts = async () => { - return await this.provider.getAccountsAsync(DEFAULT_NUM_ADDRESSES_TO_FETCH) + getAccounts = async ( + numberOfAccounts = DEFAULT_NUM_ADDRESSES_TO_FETCH, + accountsOffSet = 0 + ) => { + return await this.provider.getAccountsAsync( + numberOfAccounts, + accountsOffSet + ) } setProvider = (provider) => { diff --git a/solidity/dashboard/src/css/choose-wallet-address.less b/solidity/dashboard/src/css/choose-wallet-address.less index 9b1c96a92d..18c7896cf3 100644 --- a/solidity/dashboard/src/css/choose-wallet-address.less +++ b/solidity/dashboard/src/css/choose-wallet-address.less @@ -22,5 +22,26 @@ ul.choose-wallet-address { margin-left: auto; } } - +} + +.choose-wallet-address__pagination { + display: flex; + flex: 1; + align-self: flex-start; + justify-content: space-between; + width: 100%; + margin-top: 1rem; + + .choose-wallet-address__pagination__item { + .h5(); + .cursor-pointer(); + + &:last-of-type { + margin-left: auto; + } + + &:hover { + text-decoration: underline; + } + } } \ No newline at end of file From 7a4a77e6b2d1e87eda938eaaa3eec3e58c832987 Mon Sep 17 00:00:00 2001 From: Rafal Czajkowski Date: Thu, 10 Sep 2020 09:48:54 +0200 Subject: [PATCH 4/4] Fix a visibility of an input type radio Fixed a visibility of an input type radio in the choose wallet address component. In this component we want a default styles radio btn. --- solidity/dashboard/src/css/choose-wallet-address.less | 1 + 1 file changed, 1 insertion(+) diff --git a/solidity/dashboard/src/css/choose-wallet-address.less b/solidity/dashboard/src/css/choose-wallet-address.less index 18c7896cf3..b23db774c2 100644 --- a/solidity/dashboard/src/css/choose-wallet-address.less +++ b/solidity/dashboard/src/css/choose-wallet-address.less @@ -12,6 +12,7 @@ ul.choose-wallet-address { } label, label input[type=radio] { cursor: pointer; + visibility: visible; } label input[type=radio] {