Skip to content

Commit

Permalink
Merge pull request #2025 from keep-network/ledger-accounts-path-bug
Browse files Browse the repository at this point in the history
Ledger live derivation path fix
  • Loading branch information
dimpar authored Sep 10, 2020
2 parents 4bb15bc + 7a4a77e commit cc170d5
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 21 deletions.
27 changes: 26 additions & 1 deletion solidity/dashboard/src/components/ChooseWalletAddress.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand All @@ -30,6 +37,24 @@ const ChooseWalletAddress = ({ addresses, onSelectAccount }) => {
</li>
))}
</ul>
{withPagination && (
<div className="choose-wallet-address__pagination">
{renderPrevBtn && (
<span
onClick={onPrev}
className="choose-wallet-address__pagination__item"
>
prev
</span>
)}
<span
onClick={onNext}
className="choose-wallet-address__pagination__item"
>
next
</span>
</div>
)}
<Button
className="btn btn-primary btn-md mt-1"
disabled={!selectedAccount}
Expand Down
44 changes: 35 additions & 9 deletions solidity/dashboard/src/components/LedgerModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,40 @@ import Button from "./Button"
import ChooseWalletAddress from "./ChooseWalletAddress"
import { isEmptyArray } from "../utils/array.utils"
import { useShowMessage, messageType } from "./Message"
import { KeepLoadingIndicator } from "./Loadable"

const LedgerModal = ({ connector, connectAppWithWallet, closeModal }) => {
const [accounts, setAccounts] = useState([])

const [isFetching, setIsFetching] = useState(false)
const [accountsOffSet, setAccountsOffSet] = useState(0)
const [ledgerVersion, setLedgerVersion] = useState("")
const showMessage = useShowMessage()

useEffect(() => {
if (ledgerVersion === "LEDGER_LIVE" || ledgerVersion === "LEDGER_LEEGACY") {
let shoudlSetState = true
if (ledgerVersion === "LEDGER_LIVE" || ledgerVersion === "LEDGER_LEGACY") {
setIsFetching(true)
connector[ledgerVersion]
.getAccounts()
.then(setAccounts)
.getAccounts(5, accountsOffSet)
.then((accounts) => {
if (shoudlSetState) {
setAccounts(accounts)
setIsFetching(false)
}
})
.catch((error) => {
if (shoudlSetState) {
setIsFetching(false)
}
showMessage({ type: messageType.ERROR, title: error.message })
})
}
}, [ledgerVersion, connector, showMessage])

return () => {
shoudlSetState = false
}
}, [ledgerVersion, connector, showMessage, accountsOffSet])

const onSelectAccount = async (account) => {
connector[ledgerVersion].defaultAccount = account
Expand Down Expand Up @@ -55,11 +73,19 @@ const LedgerModal = ({ connector, connectAppWithWallet, closeModal }) => {
ledger legacy
</Button>
</div>
{!isEmptyArray(accounts) && (
<ChooseWalletAddress
onSelectAccount={onSelectAccount}
addresses={accounts}
/>
{isFetching ? (
<KeepLoadingIndicator />
) : (
!isEmptyArray(accounts) && (
<ChooseWalletAddress
onSelectAccount={onSelectAccount}
addresses={accounts}
withPagination
renderPrevBtn={accountsOffSet > 0}
onNext={() => setAccountsOffSet((prevOffset) => prevOffset + 5)}
onPrev={() => setAccountsOffSet((prevOffset) => prevOffset - 5)}
/>
)
)}
</div>
)
Expand Down
10 changes: 8 additions & 2 deletions solidity/dashboard/src/connectors/abstract-connector.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
52 changes: 44 additions & 8 deletions solidity/dashboard/src/connectors/ledger.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -28,6 +28,8 @@ const ledgerEthereumClientFactoryAsync = async () => {

class CustomLedgerSubprovider extends LedgerSubprovider {
chainId
addressToPathMap = {}
pathToAddressMap = {}

constructor(chainId, baseDerivationPath) {
super({
Expand All @@ -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()
Expand Down Expand Up @@ -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
}
}
24 changes: 23 additions & 1 deletion solidity/dashboard/src/css/choose-wallet-address.less
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ ul.choose-wallet-address {
}
label, label input[type=radio] {
cursor: pointer;
visibility: visible;
}

label input[type=radio] {
Expand All @@ -22,5 +23,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;
}
}
}

0 comments on commit cc170d5

Please sign in to comment.