# Transfer of Ethers between accounts## IntroductionIn this section, we will guide you through the creation of an application that:* creates a transaction
* signs it using the Ledger Nano then
* sends it to the blockchain.The purpose of the application is to transfer ethers from your ethereum account on your Ledger to another account.## Tutorial PrerequisitesBefore starting, make sure you have gone through the [prerequisites](../info#prerequisites).### Receive Ether token in your Ledger Nano Ethereum Sepolia account* Create an Ethereum Sepolia account in Ledger Live
* Send Sepolia Eth to your account with [Infura faucet](https://www.infura.io/faucet/sepolia). You will need to create an account that will be useful later for the API key.![Sepolia Ethereum Faucet](/device-interaction/tutorial-infura-sepolia-faucet.png)
_Fig. 1: Sepolia Ethereum Faucet_## Tutorial implementationIn this implementation, we will be building a web application with vanilla javascript that uses the HID protocol from a [Ledger package](https://github.com/LedgerHQ/ledger-live/tree/develop/libs/ledgerjs/packages/hw-transport-webhid) to communicate with the ledger.### Project InitializationIt is time to implement the application and test it. First, open a terminal and create a new folder. For this tutorial, the folder will be named "e2e-eth-tutorial”.
Run:```console copy
mkdir e2e-eth-tutorial
cd e2e-eth-tutorial
```Initialize the project by running the following:```console copy
npm init
```Answer the questions displayed or by default press enter. There is no incidence on the execution.Run:```console copy
touch index.html
touch index.js
touch style.css
mkdir assets
```Copy the logo in the assets folder.The folder will contain these files:![Folder tutorial](/device-interaction/folder-e2e-eth.png)
_Fig. 3: Folder of the Application_### Code Implementation#### index.htmlIn index.html copy-paste the following code :```html copy
<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="style.css" />
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
      crossorigin="anonymous"
    />
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
      crossorigin="anonymous"
    ></script>
    <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
    <script type="module" src="index.js"></script>
  </head>

  <body className="m-5">
    <div
      className="d-flex flex-column justify-content-center m-5 align-items-center"
    >
      <p>Click on the bellow button to connect your Ledger Wallet</p>
      <button
        className="btn btn-primary w-25"
        data-bs-toggle="modal"
        data-bs-target="#WalletModal"
      >
        Connect your Wallet
      </button>
    </div>
    <div className="d-flex flex-row">
      <div id="app" className="w-50">
        <form className="row g-3">
          <div className="col-md-12">
            <label for="wallet" className="form-label">Wallet Public Key</label>
            <input type="text" className="form-control" id="wallet" disabled />
          </div>
          <div className="col-md-12">
            <label for="recipient" className="form-label">Recipient</label>
            <input type="text" className="form-control" id="recipient" />
          </div>
          <div className="col-md-6">
            <label for="gasPrice" className="form-label"
              >Gas Price in wei</label
            >
            <input
              type="text"
              className="form-control"
              id="gasPrice"
              disabled
            />
          </div>
          <div className="col-md-6">
            <label for="gasLimit" className="form-label"
              >Gas Limit in wei</label
            >
            <input type="text" className="form-control" id="gasLimit" />
          </div>
          <div className="col-md-6">
            <label for="chainId" className="form-label">Chain ID</label>
            <input type="text" className="form-control" id="chainId" disabled />
          </div>
          <div className="col-md-6">
            <label for="value" className="form-label">Value</label>
            <input type="text" className="form-control" id="value" />
          </div>
          <div className="col-12">
            <button type="button" id="tx-transfer" className="btn btn-primary">
              Create Transaction
            </button>
          </div>
        </form>
      </div>
      <div className="w-50 d-flex flex-column">
        <p className="url">Ropsten etherscan:</p>
        <p id="url"></p>
      </div>
    </div>

    <!-- Modal -->
    <div
      className="modal fade"
      id="WalletModal"
      tabindex="-1"
      aria-labelledby="WalletModalLabel"
      aria-hidden="true"
    >
      <div className="modal-dialog">
        <div className="modal-content">
          <div className="modal-header">
            <h5 className="modal-title" id="WalletModalLabel">
              Choose your Wallet
            </h5>
            <button
              type="button"
              className="btn-close"
              data-bs-dismiss="modal"
              aria-label="Close"
            ></button>
          </div>
          <div className="modal-body d-flex justify-content-center">
            <button
              id="connect-ledger"
              className="rounded-3 align-self-center"
              data-bs-dismiss="modal"
            >
              <img
                src="./assets/ledger-logo.jpg"
                className="card-img-top"
                alt="Ledger"
              />
            </button>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>
```#### index.jsIn index.js copy-paste the following code and replace `{YOUR_INFURA_APIKEY}` by the API key you will find on your Infura account:```javascript copy
import { ethers } from "ethers";
import { InfuraProvider } from "ethers";
import TransportWebHID from "@ledgerhq/hw-transport-webhid";
import Eth from "@ledgerhq/hw-app-eth";
import ledgerService from "@ledgerhq/hw-app-eth/lib/services/ledger";

var ethers = require("ethers");
//Infuria provider for Sepolia network
const provider = new ethers.JsonRpcProvider(
  "https://sepolia.infura.io/v3/{YOUR_INFURA_APIKEY}",
);

const chainId = 11155111; // Sepolia chainId
let gasPrice;
let addressWallet;
let recipient = "0x920f19c7F7Ce5b3170AdB94fDcC4570Da95D286b";
let value = 0.001;
let gasLimit = 1000000;
let nonce;
let _eth;

document.getElementById("connect-ledger").onclick = async function () {
  //Connecting to the Ledger Nano with HID protocol
  const transport = await TransportWebHID.create();

  //Getting an Ethereum instance and get the Ledger Nano ethereum account public key
  _eth = new Eth(transport);
  const { address } = await _eth.getAddress("44'/60'/0'/0/0", false);

  //Get some properties from provider
  addressWallet = address;
  gasPrice = (await provider.getFeeData()).gasPrice;

  //Fill the inputs with the default value
  document.getElementById("wallet").value = address;
  document.getElementById("gasPrice").value = ethers.formatUnits(
    gasPrice,
    "wei",
  );
  document.getElementById("chainId").value = chainId;
  document.getElementById("value").value = value;
  document.getElementById("recipient").value = recipient;
  document.getElementById("gasLimit").value = gasLimit;
};

document.getElementById("tx-transfer").onclick = async function () {
  //Getting information from the inputs
  addressWallet = document.getElementById("wallet").value;
  recipient = document.getElementById("recipient").value;
  value = document.getElementById("value").value;
  gasLimit = parseInt(document.getElementById("gasLimit").value);
  nonce = await provider.getTransactionCount(addressWallet, "latest");

  //Building transaction with the information gathered
  const transaction = {
    to: recipient,
    gasPrice: "0x" + parseInt(gasPrice).toString(16),
    gasLimit: ethers.toBeHex(gasLimit),
    nonce: nonce,
    chainId: chainId,
    data: "0x00",
    value: ethers.toBeHex(ethers.parseUnits(value, "ether")),
  };

  //Serializing the transaction to pass it to Ledger Nano for signing
  let unsignedTx =
    ethers.Transaction.from(transaction).unsignedSerialized.substring(2);
  const resolution = await ledgerService.resolveTransaction(unsignedTx, {}, {});

  //Sign with the Ledger Nano (Sign what you see)
  const signature = await _eth.signTransaction(
    "44'/60'/0'/0/0",
    unsignedTx,
    resolution,
  );

  //Serialize the same transaction as before, but adding the parsed signature on it
  let signedTx = ethers.Transaction.from({
    ...transaction,
    signature: {
      r: "0x" + signature.r,
      s: "0x" + signature.s,
      v: parseInt(signature.v),
    },
  }).serialized;

  //Sending the transaction to the blockchain
  const hash = (await provider.broadcastTransaction(signedTx)).hash;

  //Display the Sepolia etherscan on the screen
  const url = "https://sepolia.etherscan.io/tx/" + hash;
  document.getElementById("url").innerHTML = url;
};
```#### style.cssIn style.css copy-paste the following code :```css copy
.modal-content {
  width: 300px;
  height: 400px;
}

#connect-ledger {
  width: 17rem;
  height: 9rem;
  background-color: white;
  border: none;
}

#connect-ledger:hover {
  background-color: #edeff3;
}

.modal-body {
  background-color: #f7f9fd;
}

#url,
.url {
  text-align: center;
  margin-top: 160px;
  color: green;
}
```### Dependencies Installation#### Install the packagesRun:```console copy
npm install --save-dev parcel
npm install --save @ledgerhq/hw-app-eth
npm install --save @ledgerhq/hw-transport-webhid
npm install --save ethers
```| Package                                                                                                                          | What does it do?                                                                         |
| -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| [parcel](https://parceljs.org/)                                                                                                  | It is a build tool that will help you package your application to run it in the browser. |
| [@ledgerhq/hw-app-eth](https://github.com/LedgerHQ/ledger-live/tree/develop/libs/ledgerjs/packages/hw-app-eth)                   | It will help you ask your Ledger Nano to access the ethereum address.                    |
| [@ledgerhq/hw-transport-webhid](https://github.com/LedgerHQ/ledger-live/tree/develop/libs/ledgerjs/packages/hw-transport-webhid) | It provides you with all the methods to interact with your Ledger with an HID connexion. |
| [ethers](https://docs.ethers.io/v5/)                                                                                             | It provides you with all the methods to interact with the ethereum blockchain.           |#### Modify Package.jsonModify the 5th line: `"main": "index.js"` => `"source": "index.html"`
And ensure you have this line in scripts:```javascript copy
  "scripts": {
    "start": "parcel"
  },
```Add this at the end of the script:```javascript copy
  "alias": {
    "@ledgerhq/devices": "@ledgerhq/devices/lib-es"
  }
```Your file should now look like this:```javascript copy
{
    "name": "e2e-eth-tutorial",
    "version": "1.0.0",
    "description": "",
    "source": "index.html",
    "scripts": {
      "start": "parcel"
    },
    "author": "",
    "license": "ISC",
    "devDependencies": {
      "parcel": "^2.3.2"
    },
    "dependencies": {
      "@ledgerhq/hw-app-eth": "^6.26.0",
      "@ledgerhq/hw-transport-webhid": "^6.24.1",
      "ethers": "^5.5.4"
    },
    "alias": {
      "@ledgerhq/devices": "@ledgerhq/devices/lib-es"
    }
}
```## Tutorial Test### Start the Development ServerNow that the Setup is finished, the app has to be built to be displayed.
Start the development server:```console copy
npm run start
```Now the application is up and running. Open the browser and go to `localhost:1234`, it will display :![Application running on browser](/device-interaction/tutorial-1-view.png)
_Fig. 5: Application Running on Browser_### Plug Your Ledger DeviceBefore clicking on the text connect your Ledger to the USB port, unlock it and run the ethereum application.
The steps are described below.\
![Nano Enter Code Pin](/device-interaction/ledgerCodePin.jpg)Fig. 6: Nano Enter Code Pin\
![Run Ethereum Application on Ledger Nano](/device-interaction/ledgerEth.jpg)Fig. 7: Run Ethereum Application on Ledger Nano\
![Ethereum Application is Running on Ledger Nano](/device-interaction/ledgerReady.jpg)Fig. 8: Ethereum Application is Running on Ledger Nano### Connect Your Ledger to the ApplicationNow you can click on the "Connect your Wallet" button and a modal will be opened.
Click on the Ledger logo.![Choice of Wallet](/device-interaction/tutorial-1-connect.png)
_Fig. 9: Choice of Walle&#x74;_Now choose the Ledger Nano to connect it to the browser.![Connect the Ledger Nano](/device-interaction/tutorial-1-pairing.png)
_Fig. 10: Connect the Ledger Nan&#x6F;_If all goes well, the input fields will be filled with data. The greyed input is not to be changed and it is directly extracted either from the blockchain or from your Ledger Embedded application.![Application After Connecting Ledger Nano](/device-interaction/tutorial-1-view2.png)
_Fig. 11: Application After Connecting Ledger Nano_### Create a transaction to transfer ethereumNow that the inputs are filled with data. It is time to transfer some ether tokens from your Ledger ethereum account to another account (you can keep the default account on the "index.js" file).\
Therefore, click on "Create Transaction" to create the transaction which will be signed by your ledger before sending it to the blockchain.![Application After Connecting Ledger Nano](/device-interaction/tutorial-1-view2.png)
_Fig. 12: Application After Connecting Ledger Nan&#x6F;_When the transaction proceed and finalize, an URL will be displayed on the screen. This URL is a link to Ropsten Etherscan to review the transaction.\
There you can find all the information concerning the transaction you have previously sent.![Result after Sending Transaction](/device-interaction/tutorial-1-result.png)
_Fig. 13: Result after Sending Transactio&#x6E;_If you go on Etherscan you can see the information of your transaction.![Result after Sending Transaction](/device-interaction/tutorial-1-etherscan.png)
_Fig. 14: Transaction Information on Sepolia Ethersca&#x6E;_Congratulations, you have successfully built your first transfer application connected with Ledger !!!
