Hardware wallets provide safer alternatives to store your private keys so that there are minimal chances of you losing your private key and hence losing the control of your wallet. With a hardware wallet like Ledger Nano S, you are not allowed to transfer your private key out of the device in plain text.
In this blog, we look into the connection set up with the ledger app and providing users a list of wallets from which he can choose.
1) Installing the Ethereum app
2) Libraries for Ledger Integration
a) @ledgerhq/hw-transport-u2f - Allows to communicate with Ledger Hardware Wallets
Install these libraries in your project and you can use them through
3) Start integrating these libraries
We are going to integrate these libraries and will cover the functionality in the following steps
A) Verifying the connection with the user Ledger Wallet
In the above code, we do the following things
a) We check using the Transport library if the browser user is using is u2f compatible or not, if not we display the error message about u2f incompatible browser message.
b) If the browser is u2f compatible, we pass the transport connection details to the Eth constructor which allows us to perform various functions like sending transactions, generating addresses, and their verification based on parameters.
c) Now we fetch the hdPath used by the ethereum application on the ledger, and fetch the payload details using the getAddress function and save the payload details for address generation for the next step.
d) If there is still any error getting the payload details, which can be due to the reasons like the user has not opened the app, or the ledger device is not unlocked while interacting with our web application, we show him a generic message for the same.
The real error scenarios in the d) case result in TransportError or TransportStatusError, but we have updated the name and message of the errors to show the user a general message.
B) Generating user wallet addresses
In our app, we can generate multiple ethereum addresses and then let the user choose which address he wants to use, to comply with some regulations we can also add a verification step, which is processed using the getAddress call.
a) In the above code, we are using a limit of 5 max addresses whose details can be shown to the user to choose from
b) We fetch the payload details from the last step using the ledgerPayload variable , we call the create wallet function 5 times
c) In each iteration of the HDWalletCreate function, we generate a child public key, and through it the address using the index value provided.
For example - the Ethereum app uses the path m/44'/60'/0', and we are generating the public key for the children of this node in HD wallet tree, from child number 0 to 4 in case of the limit being set to 5.
d) Then we fetch the balance of all these addresses using the web3 getBalance api, and return an array of objects with fields, address, and balance and let the user choose one of the addresses.
e) Once the user chooses an address we store the correct hdPath details, initial HD Path along with the wallet index through which the user wants to interact, into the local storage, to retrieve it later for sending transactions.
f) We also update the payload variable to empty string, as we don't need to derive anything from the base public key and base chain code, once we have generated and passed the keys to the user.