diff --git a/apps/docs/package.json b/apps/docs/package.json index 8fd00ce78..1e486432c 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -24,6 +24,7 @@ "nextra-theme-docs": "^3.0.15", "react": "^18.3.1", "react-dom": "^18.3.1", + "react-medium-image-zoom": "5.1.8", "tailwindcss": "^3.4.16", "tailwind-merge": "^1.14.0" }, diff --git a/apps/docs/pages/docs/ledgerjs/_meta.js b/apps/docs/pages/docs/ledgerjs/_meta.js index 314b3c27f..443c74bb2 100644 --- a/apps/docs/pages/docs/ledgerjs/_meta.js +++ b/apps/docs/pages/docs/ledgerjs/_meta.js @@ -1,7 +1,7 @@ export default { - info: "Info note", - beginner: "Beginner's guides", - integration: "Integration walkthroughs", - references: "References", - explanation: "Explanation" -} + info: "Info note", + beginner: "Beginner's guides", + integration: "Integration walkthroughs", + references: "References", + explanation: "Explanation", +}; diff --git a/apps/docs/pages/docs/ledgerjs/beginner/_meta.js b/apps/docs/pages/docs/ledgerjs/beginner/_meta.js index 127bbb732..f1d1836b0 100644 --- a/apps/docs/pages/docs/ledgerjs/beginner/_meta.js +++ b/apps/docs/pages/docs/ledgerjs/beginner/_meta.js @@ -1,7 +1,7 @@ -export default { - 'transfer-eth': "Transfer of Ethers between accounts", - 'transfer-sol': "Transfer of Sol between accounts", - 'smart-contract': "Call a Smart Contract", - 'personal-message': "Sign a personnal message", - 'cosmos-app': "Interact with the Cosmos app" -} \ No newline at end of file +export default { + "transfer-eth": "Transfer of Ethers between accounts", + "transfer-sol": "Transfer of Sol between accounts", + "smart-contract": "Call a Smart Contract", + "personal-message": "Sign a personnal message", + "cosmos-app": "Interact with the Cosmos app", +}; diff --git a/apps/docs/pages/docs/ledgerjs/beginner/cosmos-app.mdx b/apps/docs/pages/docs/ledgerjs/beginner/cosmos-app.mdx index a1c0bc744..1f786de3c 100644 --- a/apps/docs/pages/docs/ledgerjs/beginner/cosmos-app.mdx +++ b/apps/docs/pages/docs/ledgerjs/beginner/cosmos-app.mdx @@ -1,20 +1,19 @@ --- title: Interact with the Cosmos App -description: In this section, we will guide you through the creation of a web application. This application will connect to your Nano and will allow you to use the Cosmos Embedded App. +description: In this section, we will guide you through the creation of a web application. This application will connect to your Nano and will allow you to use the Cosmos Embedded App. --- -import Zoom from 'react-medium-image-zoom' -import 'react-medium-image-zoom/dist/styles.css' -import Image from 'next/image' - +import Zoom from "react-medium-image-zoom"; +import "react-medium-image-zoom/dist/styles.css"; +import Image from "next/image"; # Interact with the Cosmos App -## Introduction +## Introduction + +In this section, we will guide you through the creation of a web application. This application will connect to your Nano and will allow you to use the Cosmos Embedded App. -In this section, we will guide you through the creation of a web application. This application will connect to your Nano and will allow you to use the Cosmos Embedded App. - -Web USB and Web HID applications are implemented with `@ledgerhq/hw-transport-webusb` and `@ledgerhq/hw-transport-webhid` respectively. +Web USB and Web HID applications are implemented with `@ledgerhq/hw-transport-webusb` and `@ledgerhq/hw-transport-webhid` respectively. This web application was originally developed by the Zondax team (here is a link to [their website](https://zondax.ch/) and to their [Twitter feed](https://twitter.com/_zondax_)) through [this source repo](https://github.com/cosmos/ledger-cosmos-js.git)). Zondax has been developing innovative end-to-end software solutions that are used by a large number of exchanges, hardware wallets, privacy coins, and decentralized finance (DeFi) protocols. Zondax has proven to be a reliable partner for Ledger apps development with more than 35 applications built to date. @@ -36,30 +35,33 @@ You will be able to do the following actions: First, open a terminal and create a new folder in your usual working directory. For this tutorial, the folder will be named “use-cosmos-webapp”. Run: + ```bash copy mkdir use-cosmos-webapp cd use-cosmos-webapp ``` Clone the repo (master branch) and go to the repo folder: + ```bash copy git clone https://github.com/LedgerHQ/ledger-cosmos-js.git cd ledger-cosmos-js ``` Run: + ```bash copy -yarn install -npm install -g @vue/cli +yarn install +npm install -g @vue/cli npm install -g @vue/cli-plugin-typescript npm install vue-template-compiler npm install --save-dev webpack ``` - ## Usage Now, that all the needed packages are installed, you can launch the webapp by runnig: + ```bash copy npm run serve ``` @@ -68,29 +70,28 @@ The application is up and running. Open the browser and go to `http://localhost: ![Cosmos integration example](/device-interaction/cosmos-01.png) -- Make sure to select the **WebUSB** option (as the U2F option is deprecated). +- Make sure to select the **WebUSB** option (as the U2F option is deprecated). - Connect your Nano to the USB port, unlock it and run the cosmos application. You’re now able to interact with the cosmos application. - Click on **Get Version**: - Cosmos integration example + Cosmos integration example - You’re able to retrieve the app version installed on your Ledger Nano device and some other information using the `getVersion()` function. - Click on **AppInfo**: - Cosmos integration example + Cosmos integration example You’re able to retrieve the app version but also the app name and some other information using the `appInfo()` function. @@ -98,10 +99,10 @@ You’re able to retrieve the app version but also the app name and some other i - Click on **Get pubkey only**: - Cosmos integration example + Cosmos integration example You can retrieve the data contained in the public key and some other information using the `getPublicKey()` function. @@ -109,122 +110,168 @@ You can retrieve the data contained in the public key and some other information - Click on **Get Address and Pubkey**: - Cosmos integration example + Cosmos integration example - You can retrieve the public address, the data contained in the public key and some other information using the `getAddress()` and `getPublicKey()` functions. - Click on **Show Address and Pubkey**: - - Cosmos integration example - - - As in the previous step, you can retrieve the public address, the data contained in the public key and some other information, but here you can preview the public address on your Nano. The address you see on the Nano is the same as what you can have on your web app. In this case, the `showAddressAndPubKey()` function is used. - - - Press the right button to do the review: - -
-
- Cosmos integration example -
- - - Verify that the correct address is showing on your Nano. Then, you can press the right button to approve or reject. -
-
- Cosmos integration example -
- - - You can confirm by pressing both buttons. -
-
- Cosmos integration example -
- - - You can also reject. -
-
- Cosmos integration example -
- - After approving the review, the webapp will display to you the public address, the data of the public key and some other information. - -- Click on **Sign Example TX**: + + Cosmos integration example + + + As in the previous step, you can retrieve the public address, the data contained in the public key and some other information, but here you can preview the public address on your Nano. The address you see on the Nano is the same as what you can have on your web app. In this case, the `showAddressAndPubKey()` function is used. + + - Press the right button to do the review: + +
+
+ Cosmos integration example +
+ + - Verify that the correct address is showing on your Nano. Then, you can press the right button to approve or reject. + +
+
+ Cosmos integration example +
+ + - You can confirm by pressing both buttons. + +
+
+ Cosmos integration example +
+ + - You can also reject. +
+
+ Cosmos integration example +
+ + After approving the review, the webapp will display to you the public address, the data of the public key and some other information. + +- Click on **Sign Example TX**: ![Cosmos integration example](/device-interaction/cosmos-07.png) -Here, it provides you with an example of a transaction to sign on your Ledger Nano device using the `signExampleTx()` function. You’ll have to review the Chain ID, the Account, the Sequence, the Type, the Amount, the Delegator, the Validator, the Memo, the Fees and the Gas. Then you can approve or decline the transaction. +Here, it provides you with an example of a transaction to sign on your Ledger Nano device using the `signExampleTx()` function. You’ll have to review the Chain ID, the Account, the Sequence, the Type, the Amount, the Delegator, the Validator, the Memo, the Fees and the Gas. Then you can approve or decline the transaction. -
+
- Cosmos integration example + Cosmos integration example
-
+
- Cosmos integration example + Cosmos integration example
-
+
- Cosmos integration example + Cosmos integration example
-
+
- Cosmos integration example + Cosmos integration example
-
+
- Cosmos integration example + Cosmos integration example
-
+
- Cosmos integration example + Cosmos integration example
-
+
- Cosmos integration example + Cosmos integration example
-
+
- Cosmos integration example + Cosmos integration example
-
+
- Cosmos integration example + Cosmos integration example
-
+
- Cosmos integration example + Cosmos integration example
-
+
- Cosmos integration example + Cosmos integration example
-
+
- Cosmos integration example + Cosmos integration example
- If approved, your transaction is signed and the webapp will display it along with the type of transaction (here, a signature) and some other information. ![Cosmos integration example](/device-interaction/cosmos-08.png) - - diff --git a/apps/docs/pages/docs/ledgerjs/beginner/personal-message.mdx b/apps/docs/pages/docs/ledgerjs/beginner/personal-message.mdx index 49674a427..75b533bd1 100644 --- a/apps/docs/pages/docs/ledgerjs/beginner/personal-message.mdx +++ b/apps/docs/pages/docs/ledgerjs/beginner/personal-message.mdx @@ -3,11 +3,10 @@ title: Sign a personal message description: In this section, we will guide you through the creation of a web application. This application will connect to your Nano and will display the “test“ message to be signed with an Ethereum account using the personal sign message functionality introduced by EIP-191. --- -import { Callout } from 'nextra/components' -import Zoom from 'react-medium-image-zoom' -import 'react-medium-image-zoom/dist/styles.css' -import Image from 'next/image' - +import { Callout } from "nextra/components"; +import Zoom from "react-medium-image-zoom"; +import "react-medium-image-zoom/dist/styles.css"; +import Image from "next/image"; # Sign a personal message @@ -19,11 +18,11 @@ Web USB and Web HID applications are implemented with `@ledgerhq/hw-transport-we ## Use case -This tutorial will let you sign a message with your private key in order to verify and prove that you’re the owner of the address. +This tutorial will let you sign a message with your private key in order to verify and prove that you’re the owner of the address. ## Tutorial Prerequisites -- Ensure you have gone through the [prerequisites](../getting-started#prerequisites). +- Ensure you have gone through the [prerequisites](../getting-started#prerequisites). - Install or update your Ethereum Embedded App to the version 1.9.19 or later. ## Coding @@ -39,14 +38,12 @@ mkdir example-sign-personal-message cd example-sign-personal-message ``` - Initialize the project by running: ```bash copy npm init ``` - Answer the questions displayed or by default press enter. There is no incidence on the execution. Run: @@ -61,7 +58,6 @@ The folder will contain these files: ![Folder USB and HID](/device-interaction/folderUsbHid.png) - ### Coding Open the folder example-sign-personal-message in a code editor. @@ -73,31 +69,32 @@ In index.html copy and paste the following code: ```html copy - - - My First Embedded App - - - -
- -
- - + + + My First Embedded App + + + +
+ + ``` - -#### main.js +#### main.js In main.js copy and paste the following code: - Comment out or remove the Transport package you are not using (@ledgerhq/hw-transport-webusb or @ledgerhq/hw-transport-webhid) and the corresponding const. In the example, we use webusb. Webhid is already commented in line 8 and line 23. + Comment out or remove the Transport package you are not using ( + @ledgerhq/hw-transport-webusb or{" "} + @ledgerhq/hw-transport-webhid) and the corresponding{" "} + const. In the example, we use webusb. Webhid is already commented + in line 8 and line 23. ```js copy -import 'core-js/actual'; +import "core-js/actual"; import { listen } from "@ledgerhq/logs"; import Eth from "@ledgerhq/hw-app-eth"; @@ -107,57 +104,58 @@ import Eth from "@ledgerhq/hw-app-eth"; import TransportWebHID from "@ledgerhq/hw-transport-webhid"; //Display the header in the div which has the ID "main" -const initial = "

Connect your Nano and open the Ethereum app. Click on “Hash my message”

"; +const initial = + "

Connect your Nano and open the Ethereum app. Click on “Hash my message”

"; const $main = document.getElementById("main"); $main.innerHTML = initial; document.querySelector("#hashMessage").addEventListener("click", async () => { - $main.innerHTML = initial; - try { - - //trying to connect to your Ledger device with USB protocol - // const transport = await TransportWebUSB.create(); - - //trying to connect to your Ledger device with HID protocol - const transport = await TransportWebHID.create(); - - //listen to the events which are sent by the Ledger packages in order to debug the app - listen(log => console.log(log)) - - //When the Ledger device connected it is trying to display the bitcoin address - const eth = new Eth(transport); - const signature = await eth.signPersonalMessage("44'/60'/0'/0/0", Buffer.from("test").toString("hex")); - const signedHash = "0x" + signature.r + signature.s + signature.v.toString(16); - - //Display your bitcoin address on the screen - const h2 = document.createElement("h2"); - h2.textContent = signedHash; - $main.innerHTML = "

Your signed message:

"; - $main.appendChild(h2); - - //Display the address on the Ledger device and ask to verify the address - const { address } = await eth.getAddress("44'/60'/0'/0/0"); - const add = document.createElement("div"); - add.textContent = address - $main.appendChild(add); - } catch (e) { - - //Catch any error thrown and displays it on the screen - const $err = document.createElement("code"); - $err.style.color = "#f66"; - $err.textContent = String(e.message || e); - $main.appendChild($err); - } + $main.innerHTML = initial; + try { + //trying to connect to your Ledger device with USB protocol + // const transport = await TransportWebUSB.create(); + + //trying to connect to your Ledger device with HID protocol + const transport = await TransportWebHID.create(); + + //listen to the events which are sent by the Ledger packages in order to debug the app + listen((log) => console.log(log)); + + //When the Ledger device connected it is trying to display the bitcoin address + const eth = new Eth(transport); + const signature = await eth.signPersonalMessage( + "44'/60'/0'/0/0", + Buffer.from("test").toString("hex"), + ); + const signedHash = + "0x" + signature.r + signature.s + signature.v.toString(16); + + //Display your bitcoin address on the screen + const h2 = document.createElement("h2"); + h2.textContent = signedHash; + $main.innerHTML = "

Your signed message:

"; + $main.appendChild(h2); + + //Display the address on the Ledger device and ask to verify the address + const { address } = await eth.getAddress("44'/60'/0'/0/0"); + const add = document.createElement("div"); + add.textContent = address; + $main.appendChild(add); + } catch (e) { + //Catch any error thrown and displays it on the screen + const $err = document.createElement("code"); + $err.style.color = "#f66"; + $err.textContent = String(e.message || e); + $main.appendChild($err); + } }); ``` - - ## Dependencies Installation ### Install the packages -Run: +Run: ```bash copy npm install --save core-js @@ -172,13 +170,13 @@ npm install --save-dev stream-browserify ### Install the Transport HID or USB package -Then depending on your choice install one of the corresponding packages: +Then depending on your choice install one of the corresponding packages: + - Install the Ledger package `@ledgerhq/hw-transport-webhid` which provide you with all the methods to interact with your Nano with an HID connection (make sure that you use the 6.27.1 version): -`npm install --save @ledgerhq/hw-transport-webhid@6.27.1` + `npm install --save @ledgerhq/hw-transport-webhid@6.27.1` - Install the Ledger package `@ledgerhq/hw-transport-webusb` which provide you with all the methods to interact with your Nano with a USB connection (make sure that you use the 6.27.1 version): -`npm install --save @ledgerhq/hw-transport-webusb@6.27.1` - + `npm install --save @ledgerhq/hw-transport-webusb@6.27.1` ### Package.json @@ -194,6 +192,7 @@ Ensure you have this line in your `package.json`: ``` And: + ```json copy "alias": { @@ -242,8 +241,6 @@ Your `package.json` should look like this: } ``` - - ## Usage ### Start the development server @@ -254,11 +251,10 @@ Now that the Setup is finished, the app has to be built to be displayed. Start t npm run start ``` -Now the application is up and running. Open the browser and go to `localhost:1234`, it will display: +Now the application is up and running. Open the browser and go to `localhost:1234`, it will display: ![Hash Message](/device-interaction/hash-message.png) - ### Plug your Nano Before clicking on the “Hash my message”, connect your Nano to the USB port, unlock it and run the ethereum application. Then, click on “Hash my message”. @@ -267,38 +263,36 @@ Before clicking on the “Hash my message”, connect your Nano to the USB port, When you click on the “Hash my message”, a popup message will be prompt inviting you to sign a message. -
+
- Hash Message + Hash Message
Click the right button to see the content of the message that you are going to sign with your Ethereum address: -
+
- Hash Message + Hash Message
- ### Sign the message Click the right button to the next screens to sign the “test” message or decline it: -
+
- Hash Message + Hash Message
-
+
- Hash Message + Hash Message
Once signed, the webapp will display: + - The signed message (“hash”) - The Ethereum address used to sign the message - - ### Verify on runkit.com You can verify that you are the one who signed the message by signing in on [runkit.com](https://runkit.com/home) and running the following piece of code. @@ -307,14 +301,14 @@ You can verify that you are the one who signed the message by signing in on [run ```js copy const { ethers } = require("ethers"); -ethers.verifyMessage("test", "0xefb42c22baa0143b322e93b24b0903a0ef47a64b716fbb77debbea55a93dec3e4417aff7dce845723240916c6e34cf17c674828b3addfb0afad966334df5b6311b"); +ethers.verifyMessage( + "test", + "0xefb42c22baa0143b322e93b24b0903a0ef47a64b716fbb77debbea55a93dec3e4417aff7dce845723240916c6e34cf17c674828b3addfb0afad966334df5b6311b", +); ``` 2. Run your code, it should now display the Ethereum address linked to the signed message (the run can take a bit of time): - Runkit + Runkit diff --git a/apps/docs/pages/docs/ledgerjs/beginner/smart-contract.mdx b/apps/docs/pages/docs/ledgerjs/beginner/smart-contract.mdx index 1b61548d5..ff087ffc7 100644 --- a/apps/docs/pages/docs/ledgerjs/beginner/smart-contract.mdx +++ b/apps/docs/pages/docs/ledgerjs/beginner/smart-contract.mdx @@ -3,25 +3,26 @@ title: Call a Smart Contract description: In this section, we will guide you through the creation of an application that will call a smart contract to read and write. --- -import { Callout } from 'nextra/components' -import Image from 'next/image' - +import { Callout } from "nextra/components"; +import Image from "next/image"; # Call a Smart Contract ## Introduction + In this section, we will guide you through the creation of an application that will call a smart contract to read and write. ## Tutorial Prerequisites + Before starting, make sure you have gone through the [prerequisites](../getting-started#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. +- 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* +_Fig. 1: Sepolia Ethereum Faucet_ ## Web App Bluetooth (only Nano X) @@ -55,18 +56,17 @@ touch ./ethereum.js touch ./styles/global.css touch ./styles/Home.module.css mv src/index.js pages -mv src/App.js ./ -rm -r src +mv src/App.js ./ +rm -r src ``` -The folder will contain these files: +The folder will contain these files: ![Folder of the Application](/device-interaction/tutorial-2-folder.png) -*Fig. 1: Folder of the Application* +_Fig. 1: Folder of the Application_ To implement the Ledger connexion you will only modify "App.js", "index.js", "ConnectLedger.js”,"SmartContract.js", and ethereum.js” - ### Code Implementation #### App.js @@ -74,88 +74,87 @@ To implement the Ledger connexion you will only modify "App.js", "index.js", "Co In App.js copy-paste the following code: ```javascript copy -import React, { useState } from 'react'; -import ConnectLedger from './ConnectLedger.js'; -import SmartContract from './SmartContract.js'; - +import React, { useState } from "react"; +import ConnectLedger from "./ConnectLedger.js"; +import SmartContract from "./SmartContract.js"; + function App() { const [transport, setTransport] = useState(undefined); const [eth, setEth] = useState(undefined); const [address, setAddress] = useState(undefined); - + const saveInfo = (info) => { setAddress(info.address); setEth(info.eth); setTransport(info.transport); - } - + }; + return ( -
- { - !transport ? - saveInfo(info)}> : - - } +
+ {!transport ? ( + saveInfo(info)}> + ) : ( + + )}
); } - + export default App; ``` + #### ConnectLedger.js In ConnectLedger.js, copy-paste the following code: ```javascript copy -import React from 'react'; - +import React from "react"; + import TransportWebBLE from "@ledgerhq/hw-transport-web-ble"; import Eth from "@ledgerhq/hw-app-eth"; - - -function ConnectLedger({onTransport}) { - - const connectLedger = async() => { + +function ConnectLedger({ onTransport }) { + const connectLedger = async () => { const transport = await TransportWebBLE.create(); const eth = new Eth(transport); - const {address} = await eth.getAddress("44'/60'/0'/0/0", false); - onTransport({address,eth,transport}) - } - - + const { address } = await eth.getAddress("44'/60'/0'/0/0", false); + onTransport({ address, eth, transport }); + }; + return ( -
-
-
+
+
+
); } - + export default ConnectLedger; ``` - #### SmartContract.js In "SmartContract.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 React, { useState } from 'react'; -import getBlockchain from './ethereum.js'; -import { ethers } from 'ethers'; -import { ledgerService } from '@ledgerhq/hw-app-eth' - -function SmartContract({eth,address}) { +import React, { useState } from "react"; +import getBlockchain from "./ethereum.js"; +import { ethers } from "ethers"; +import { ledgerService } from "@ledgerhq/hw-app-eth"; + +function SmartContract({ eth, address }) { const [simpleStorage, setSimpleStorage] = useState(undefined); const [data, setData] = useState(undefined); const [provider, setProvider] = useState(undefined); const [url, setUrl] = useState(undefined); - - const smartContractRead = async() => { - const provider = new ethers.providers.JsonRpcProvider('https://sepolia.infura.io/v3/{YOUR_INFURA_APIKEY}'); + + const smartContractRead = async () => { + const provider = new ethers.providers.JsonRpcProvider( + "https://sepolia.infura.io/v3/{YOUR_INFURA_APIKEY}", + ); const { simpleStorage } = await getBlockchain(provider); console.log(simpleStorage); const data = await simpleStorage.readData(); @@ -163,13 +162,14 @@ function SmartContract({eth,address}) { setSimpleStorage(simpleStorage); setData(data); }; - - const updateData = async e => { + + const updateData = async (e) => { e.preventDefault(); const dataInput = e.target.elements[0].value; console.log(simpleStorage); - const { data } = await simpleStorage.populateTransaction['updateData(uint256)'](dataInput); - + const { data } = + await simpleStorage.populateTransaction["updateData(uint256)"](dataInput); + const unsignedTx = { to: simpleStorage.address, gasPrice: (await provider.getGasPrice())._hex, @@ -177,80 +177,78 @@ function SmartContract({eth,address}) { nonce: await provider.getTransactionCount(address, "latest"), chainId: 11155111, data: data, - } + }; console.log(unsignedTx); const defaultLoadConfig = { nftExplorerBaseURL: "https://nft.api.live.ledger.com/v1/ethereum", pluginBaseURL: "https://cdn.live.ledger.com", extraPlugins: null, - cryptoassetsBaseURL: "https://cdn.live.ledger.com/cryptoassets" + cryptoassetsBaseURL: "https://cdn.live.ledger.com/cryptoassets", }; const serializedTx = ethers.utils.serializeTransaction(unsignedTx).slice(2); - const resolution = await ledgerService.resolveTransaction(serializedTx, defaultLoadConfig, {}); - + const resolution = await ledgerService.resolveTransaction( + serializedTx, + defaultLoadConfig, + {}, + ); + console.log(serializedTx); const signature = await eth.signTransaction( "44'/60'/0'/0/0", serializedTx, - resolution + resolution, ); - + console.log(signature); //Parse the signature - signature.r = "0x"+signature.r; - signature.s = "0x"+signature.s; - signature.v = parseInt("0x"+signature.v); + signature.r = "0x" + signature.r; + signature.s = "0x" + signature.s; + signature.v = parseInt("0x" + signature.v); signature.from = address; console.log(signature); - + //Serialize the same transaction as before, but adding the signature on it const signedTx = ethers.utils.serializeTransaction(unsignedTx, signature); console.log(signedTx); - + const hash = (await provider.sendTransaction(signedTx)).hash; console.log(hash); setUrl("https://sepolia.etherscan.io/tx/" + hash); }; - - + return ( -
-
-
+
+
+

Data:

-

{data ? data.toString() : "..." }

+

{data ? data.toString() : "..."}

- -
+ +

Change data

-
updateData(e)}> - -
+

Sepolia Etherscan :

- Sepolia Etherscan : + + {url} +

-

{url}

); } - + export default SmartContract; ``` @@ -259,66 +257,65 @@ export default SmartContract; In "ethereum.js", copy-paste the following code: ```javascript copy -import { Contract } from 'ethers'; - +import { Contract } from "ethers"; + const getBlockchain = (provider) => - new Promise( async (resolve, reject) => { - if(provider) { + new Promise(async (resolve, reject) => { + if (provider) { const simpleStorage = new Contract( "0xA0aB0fae9C6b4882dC3690cb1705D5Aeb8c436d7", [ { - "inputs": [], - "name": "data", - "outputs": [ + inputs: [], + name: "data", + outputs: [ { - "internalType": "uint256", - "name": "", - "type": "uint256" - } + internalType: "uint256", + name: "", + type: "uint256", + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: "view", + type: "function", }, { - "inputs": [], - "name": "readData", - "outputs": [ + inputs: [], + name: "readData", + outputs: [ { - "internalType": "uint256", - "name": "", - "type": "uint256" - } + internalType: "uint256", + name: "", + type: "uint256", + }, ], - "stateMutability": "view", - "type": "function" + stateMutability: "view", + type: "function", }, { - "inputs": [ + inputs: [ { - "internalType": "uint256", - "name": "_data", - "type": "uint256" - } + internalType: "uint256", + name: "_data", + type: "uint256", + }, ], - "name": "updateData", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } + name: "updateData", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, ], - provider + provider, ); - resolve({simpleStorage}); + resolve({ simpleStorage }); return; } - reject('Provider not recognized'); + reject("Provider not recognized"); }); - + export default getBlockchain; ``` - ### Dependencies Installation Run: @@ -332,15 +329,16 @@ npm install --save buffer npm install --save next ``` -| Package | What does it do? | -| ------- | ---------------- | -| [bootstrap](https://getbootstrap.com/) | It allows you to use the Bootstrap CSS framework. | -| [ethers](https://docs.ethers.io/v5/) | It provides you with all the methods to interact with the Ethereum blockchain. For this tutorial, we use the 5.4.7 version. | -| [@ledgerhq/hw-app-eth](https://github.com/LedgerHQ/ledger-live/tree/develop/libs/ledgerjs/packages/hw-app-eth) | It will help you ask your Nano to access the ethereum address. | -| [@ledgerhq/hw-transport-web-ble](https://github.com/LedgerHQ/ledger-live/tree/develop/libs/ledgerjs/packages/hw-transport-web-ble) | It provides you with all the methods to interact with your Ledger Nano X with a Bluetooth connexion. | -| [buffer](https://www.npmjs.com/package/buffer) | The goal is to provide an API that is 100% identical to node's Buffer API. | +| Package | What does it do? | +| ---------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| [bootstrap](https://getbootstrap.com/) | It allows you to use the Bootstrap CSS framework. | +| [ethers](https://docs.ethers.io/v5/) | It provides you with all the methods to interact with the Ethereum blockchain. For this tutorial, we use the 5.4.7 version. | +| [@ledgerhq/hw-app-eth](https://github.com/LedgerHQ/ledger-live/tree/develop/libs/ledgerjs/packages/hw-app-eth) | It will help you ask your Nano to access the ethereum address. | +| [@ledgerhq/hw-transport-web-ble](https://github.com/LedgerHQ/ledger-live/tree/develop/libs/ledgerjs/packages/hw-transport-web-ble) | It provides you with all the methods to interact with your Ledger Nano X with a Bluetooth connexion. | +| [buffer](https://www.npmjs.com/package/buffer) | The goal is to provide an API that is 100% identical to node's Buffer API. | #### Package.json Dependencies + Now that the dependencies are installed you can find them in the "package.js". This is how your "package.json" shoud look like: @@ -390,8 +388,11 @@ This is how your "package.json" shoud look like: } } ``` + ## Web App Test + ### Start the Development Server + Run: ```console copy @@ -399,129 +400,188 @@ npm run dev ``` - All the browser do not support the Bluetooth please look at the browser support . + All the browser do not support the Bluetooth please look at the{" "} + + {" "} + browser support{" "} + + . Now the application is up and running. Open the browser and go to `localhost:3000`, it will display : ![Application Running on Browser](/device-interaction/tutorial-2-connect.png) -*Fig. 2: Application Running on Browser* +_Fig. 2: Application Running on Browser_ Don't click on the button yet. ### Launch the Ethereum App + Before clicking on the button, unlock your Nano X and run the Ethereum application. The steps are described below. -
+
- Nano Enter Code Pin -
Fig. 3: Ledger Enter Code Pin
+ Nano Enter Code Pin +
+ Fig. 3: Ledger Enter Code Pin +
-
+
- Embedded Application -
Fig. 4: Ledger Application
+ Embedded Application +
+ Fig. 4: Ledger Application +
-
+
- Nano Run Application -
Fig. 5: Application is running
+ Nano Run Application +
+ Fig. 5: Application is running +
- For the tutorial to work, go to the Ethereum app settings and enable Blind Signing. + For the tutorial to work, go to the Ethereum app settings and enable Blind + Signing. - ### Connect Your Nano to the Application + Now you can click on the button and a popup opens. Choose your Ledger Nano X and click connexion. ![Connect the Ledger with Bluetooth](/device-interaction/tutorial-2-pairing.png) -*Fig. 6: Connect the Ledger with Bluetooth* +_Fig. 6: Connect the Ledger with Bluetooth_ ### Read the data of a Smart Contract + Now you can click on the button "Get Data" to read the data of the smart contract. Then the data will be displayed on the screen. ![Get data from a smart contract](/device-interaction/tutorial-2-getdata.png) -*Fig. 7: Get data from a smart contract* - +_Fig. 7: Get data from a smart contract_ ### Update the data of a Smart Contract + Now instead of reading data, we will overwrite the data by calling a function of the smart contract which is "UpdateData". ![Change data from a smart contract](/device-interaction/tutorial-2-changedata.png) -*Fig. 8: Change data from a smart contract* +_Fig. 8: Change data from a smart contract_ ### Verify the Address on your Nano + For security reasons, the address will also be displayed on your Ledger Nano X to verify and confirm the address. -
+
- Nano Review Screen -
- Nano Blind Signing alert -
- Nano Amount Screen -
Fig. 9: Nano Review Screen
-
Fig. 10: Blind Signing info Screen
-
Fig. 11: Nano Amount Screen
+ Nano Review Screen +
+ Nano Blind Signing alert +
+ Nano Amount Screen +
+ Fig. 9: Nano Review Screen +
+
+ Fig. 10: Blind Signing info Screen +
+
+ Fig. 11: Nano Amount Screen +
-
+
- Nano Address Screen -
- Nano Network Screen -
Fig. 12: Nano Address Screen
-
Fig. 13: Nano Network Screen
+ Nano Address Screen +
+ Nano Network Screen +
+ Fig. 12: Nano Address Screen +
+
+ Fig. 13: Nano Network Screen +
-
+
- Nano Max Fees Screen -
- Nano Accept and Send Screen -
Fig. 14: Nano Max Fees Screen
-
Fig. 15: Nano Accept and Send Screen
+ Nano Max Fees Screen +
+ Nano Accept and Send Screen +
+ Fig. 14: Nano Max Fees Screen +
+
+ Fig. 15: Nano Accept and Send Screen +
- For the Smart Contract call you need to allow blind signing because the smart contract that is called in the tutorial is not yet verified and reviewed by Ledger. But if the smart contract you are calling is accepted by Ledger do not enable blind signing. Moreover, we do not recommend enabling blind signing in other situations as the main purpose to sign with Ledger is the 'Sign what you see' system. And by enabling blind signing it can not ensure that what you see is what you get. + For the Smart Contract call you need to allow blind signing because the smart + contract that is called in the tutorial is not yet verified and reviewed by + Ledger. But if the smart contract you are calling is accepted by Ledger do not + enable blind signing. Moreover, we do not recommend enabling blind signing in + other situations as the main purpose to sign with Ledger is the 'Sign what you + see' system. And by enabling blind signing it can not ensure that what you see + is what you get. - ### Review the Transaction on Sepolia Etherscan + By updating the data a transaction is created to change this data, it can be verified on Sepolia Etherscan. -![Sepolia Etherscan](/device-interaction/tutorial-2-etherscan1.png) -*Fig. 15: Sepolia Etherscan* +![Sepolia Etherscan](/device-interaction/tutorial-2-etherscan1.png) +_Fig. 15: Sepolia Etherscan_ Wait till the status passes to Success. -![Sepolia Etherscan](/device-interaction/tutorial-2-etherscan2.png) -*Fig. 16: Sepolia Etherscan* +![Sepolia Etherscan](/device-interaction/tutorial-2-etherscan2.png) +_Fig. 16: Sepolia Etherscan_ ### Verify the update of data Finally, to verify if data was updated, open the web application and click on "Get data". ![Verify the data](/device-interaction/tutorial-2-getdata2.png) -*Fig. 17: Verify the data* +_Fig. 17: Verify the data_ -![Verify the data](/device-interaction/tutorial-2-getdata3.png) -*Fig. 18: Verify the data* +![Verify the data](/device-interaction/tutorial-2-getdata3.png) +_Fig. 18: Verify the data_ -Congratulations, you have successfully built your first application connected with Ledger! \ No newline at end of file +Congratulations, you have successfully built your first application connected with Ledger! diff --git a/apps/docs/pages/docs/ledgerjs/beginner/transfer-eth.mdx b/apps/docs/pages/docs/ledgerjs/beginner/transfer-eth.mdx index f70c43dec..019a60579 100644 --- a/apps/docs/pages/docs/ledgerjs/beginner/transfer-eth.mdx +++ b/apps/docs/pages/docs/ledgerjs/beginner/transfer-eth.mdx @@ -3,36 +3,38 @@ title: Transfer of Ethers between accounts description: In this section, we will guide you through the creation of an application. This application will create a transaction that will be signed with the Ledger Nano before sending it to the blockchain. --- -import Image from 'next/image' - +import Image from "next/image"; # Transfer of Ethers between accounts ## Introduction -In 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. + +In 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 Prerequisites + Before starting, make sure you have gone through the [prerequisites](../getting-started#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. +- 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* - +_Fig. 1: Sepolia Ethereum Faucet_ ## Tutorial implementation In 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 Initialization + It 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: @@ -60,10 +62,10 @@ mkdir assets Copy [the logo](../faq/ledger-logos) in the assets folder. -The folder will contain these files: +The folder will contain these files: ![Folder tutorial](/device-interaction/folder-e2e-eth.png) -*Fig. 3: Folder of the Application* +_Fig. 3: Folder of the Application_ ### Code Implementation @@ -77,67 +79,116 @@ In index.html copy-paste the following code : Parcel Sandbox - - - + + + -
+

Click on the bellow button to connect your Ledger Wallet

- +
- +
- +
- - + +
- - + +
- +
- +
- +
-

Ropsten etherscan:

-

+

Ropsten etherscan:

+

-