-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs(tutorial): Build a live app from the ground up (#239)
* docs(tutorial): Build a live app from the ground up * docs(tutorial): Add Next Scaffolding and references
- Loading branch information
1 parent
b5ef441
commit eae3598
Showing
6 changed files
with
386 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"start": "Start here", | ||
"configuration": "Configuration", | ||
"hooking-up": "Hooking up", | ||
"manifest": "Import your app in Ledger Live" | ||
} |
105 changes: 105 additions & 0 deletions
105
apps/docs/pages/examples/live-app-creation/configuration.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { Callout } from "nextra/components"; | ||
|
||
### 4. **Configuring Ledger's Wallet API** | ||
|
||
To interact with Ledger Live, you'll need to configure the Ledger's Wallet API. The first step is to install the necessary packages, and then set up the appropriate configuration through a transport layer named "Transport". This transport layer will enable communication with the Wallet API. | ||
|
||
- **Installing Packages**: | ||
Install the necessary packages using npm: | ||
|
||
```sh | ||
npm install @ledgerhq/wallet-api-client @ledgerhq/wallet-api-client-react | ||
``` | ||
|
||
- **Creating Transport Provider**: | ||
Create a file named `TransportProvider.tsx`. This file will contain a component that utilizes the Ledger Wallet API client to create a communication transport Higher Order Component (HOC). | ||
|
||
```jsx | ||
// src/TransportProvider.tsx | ||
import { WalletAPIProvider } from "@ledgerhq/wallet-api-client-react"; | ||
import { Transport, WindowMessageTransport } from "@ledgerhq/wallet-api-client"; | ||
|
||
function TransportProvider({ children }) { | ||
function getWalletAPITransport(): Transport { | ||
if (typeof window === "undefined") { | ||
return { | ||
onMessage: undefined, | ||
send: () => {} | ||
}; | ||
} | ||
|
||
const transport = new WindowMessageTransport(); | ||
transport.connect(); | ||
return transport; | ||
} | ||
|
||
const transport = getWalletAPITransport(); | ||
|
||
return ( | ||
<WalletAPIProvider transport={transport}>{children}</WalletAPIProvider> | ||
); | ||
} | ||
|
||
export default TransportProvider; | ||
``` | ||
|
||
- **Wrapping App with TransportProvider**: | ||
In your root file, wrap your `<App />` with the `TransportProvider`: | ||
|
||
```jsx | ||
// src/index.tsx or src/index.js | ||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import App from './App'; | ||
import TransportProvider from './TransportProvider'; | ||
|
||
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( | ||
<React.StrictMode> | ||
<TransportProvider> | ||
<App /> | ||
</TransportProvider> | ||
</React.StrictMode> | ||
); | ||
``` | ||
|
||
With this setup, your entire application can access Ledger's Wallet API and communicate with it via the `TransportProvider`. | ||
|
||
### 5. **Setting Up The Simulator** | ||
|
||
During the development and testing phases, the Ledger Wallet API simulator can help you develop without requiring to run Ledger Live in parallel. | ||
You can modify your `TransportProvider.tsx` file to use the `getSimulatorTransport` function provided by the simulator library. | ||
|
||
```jsx | ||
// src/TransportProvider.tsx | ||
import { WalletAPIProvider } from "@ledgerhq/wallet-api-client-react"; | ||
import { getSimulatorTransport, profiles } from "@ledgerhq/wallet-api-simulator"; | ||
import type { Transport } from "@ledgerhq/wallet-api-core"; | ||
|
||
function TransportProvider({ children }) { | ||
function getWalletAPITransport(): Transport { | ||
if (typeof window === "undefined") { | ||
return { | ||
onMessage: undefined, | ||
send: () => {}, | ||
}; | ||
} | ||
|
||
// Use Simulator transport | ||
const transport = getSimulatorTransport(profiles.STANDARD); | ||
|
||
return transport; | ||
} | ||
|
||
const transport = getWalletAPITransport(); | ||
|
||
return ( | ||
<WalletAPIProvider transport={transport}>{children}</WalletAPIProvider> | ||
); | ||
} | ||
|
||
export default TransportProvider; | ||
``` | ||
|
||
<Callout emoji="💡"> | ||
For more informations regarding the simulator, please checkout out [the simulator subsection](/react/simulator) | ||
</Callout> |
123 changes: 123 additions & 0 deletions
123
apps/docs/pages/examples/live-app-creation/hooking-up.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
### 6. **Fetching Account Information** | ||
|
||
With your environment set up, you can now start interacting with the Ledger Wallet API. Create a new file under the `/hooks` directory named `useAccounts.tsx`. This file will house a custom hook to fetch user account information using the `useAccounts` hook provided by Ledger. | ||
|
||
```jsx | ||
// src/hooks/useAccounts.tsx | ||
import { useAccounts } from "@ledgerhq/wallet-api-client-react"; | ||
|
||
function useUserAccounts() { | ||
const { accounts, loading, error } = useAccounts(); | ||
|
||
return { | ||
accounts, | ||
loading, | ||
error, | ||
}; | ||
} | ||
|
||
export default useUserAccounts; | ||
``` | ||
|
||
Now, you can use this custom hook in your components to fetch and display user account information. | ||
|
||
### 7. **Creating Transaction Signing Functionality** | ||
|
||
Now that you can fetch account information, the next step is to facilitate transaction signing within your app. Create a new file under the `/hooks` directory named `useSignTransaction.tsx`. This file will contain a custom hook to sign transactions using the `useSignTransaction` hook provided by Ledger. | ||
|
||
```jsx | ||
// src/hooks/useSignTransaction.tsx | ||
import { useSignTransaction, useRequestAccount } from '@ledgerhq/wallet-api-client-react'; | ||
import { useCallback, useState, useEffect } from 'react'; | ||
import BigNumber from 'bignumber.js'; | ||
|
||
function useTransactionSigner() { | ||
const { requestAccount, account } = useRequestAccount(); | ||
const { signTransaction, pending, signature, error } = useSignTransaction(); | ||
const [response, setResponse] = useState(null); | ||
|
||
useEffect(() => { | ||
requestAccount(); | ||
}, [requestAccount]); | ||
|
||
const handleSignTransaction = useCallback(async () => { | ||
if (!account) return; | ||
|
||
const ethereumTransaction = { | ||
family: 'ethereum', | ||
amount: new BigNumber(1000000000000000), // 0.001 ETH in wei | ||
recipient: '0xRecipientAddressHere', | ||
gasPrice: new BigNumber(20000000000), // 20 Gwei | ||
gasLimit: new BigNumber(21000), | ||
nonce: 0, // Replace with the correct nonce | ||
}; | ||
|
||
try { | ||
const signature = await signTransaction(account.id, ethereumTransaction); | ||
setResponse(signature); | ||
} catch (e) { | ||
console.error(e); | ||
} | ||
}, [account, signTransaction]); | ||
|
||
return { | ||
handleSignTransaction, | ||
pending, | ||
response, | ||
error | ||
}; | ||
} | ||
|
||
export default useTransactionSigner; | ||
``` | ||
|
||
### 8. **Building User Interface** | ||
|
||
Now it's time to create the UI where users will interact with your app. Create a new file named `App.tsx` under the `/src` directory. | ||
|
||
```jsx | ||
// src/App.tsx | ||
import React from 'react'; | ||
import useUserAccounts from './hooks/useAccounts'; | ||
import useTransactionSigner from './hooks/useSignTransaction'; | ||
|
||
function App() { | ||
const { accounts, loading, error } = useUserAccounts(); | ||
const { handleSignTransaction, pending, response, error: signError } = useTransactionSigner(); | ||
|
||
return ( | ||
<> | ||
<h1>User's Crypto Accounts</h1> | ||
{loading ? ( | ||
<p>Loading...</p> | ||
) : error ? ( | ||
<p>Error: {error.message}</p> | ||
) : ( | ||
<ul> | ||
{(accounts ?? []).map(({ id, name, address, currency, balance }) => ( | ||
<li key={id}> | ||
<p>id: {id}</p> | ||
<p>name: {name}</p> | ||
<p>address: {address}</p> | ||
<p>currency: {currency}</p> | ||
{/* Make sure to parse BigNumber */} | ||
<p>balance: {balance.toString()}</p> | ||
</li> | ||
))} | ||
</ul> | ||
)} | ||
<button onClick={handleSignTransaction} disabled={pending}> | ||
Sign Ethereum Transaction | ||
</button> | ||
{pending && <p>Signing...</p>} | ||
{signError && <p>Error: {signError.toString()}</p>} | ||
{response && <p>Transaction signed successfully: {response.toString('hex')}</p>} | ||
</> | ||
); | ||
} | ||
export default App; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { Callout } from "nextra/components"; | ||
|
||
### 9. **Creating a Manifest File** | ||
|
||
A manifest file is necessary to test your Live App inside Ledger Live. Create a `manifest.json` file at the root of your project. Here is a sample manifest you can use: | ||
|
||
```json | ||
{ | ||
"id": "SampleLiveApp", | ||
"name": "SampleLiveApp", | ||
"url": "http://localhost:3000/", | ||
"params": { | ||
"dappUrl": "http://localhost:3000/", | ||
"nanoApp": "SampleLiveApp", | ||
"dappName": "SampleLiveApp", | ||
"networks": [ | ||
{ | ||
"currency": "ethereum", | ||
"chainID": 1, | ||
"nodeURL": "..." | ||
} | ||
] | ||
}, | ||
"homepageUrl": "http://localhost:3000/", | ||
"platform": ["ios","android","desktop"], | ||
"apiVersion": "^2.0.0", | ||
"manifestVersion": "2", | ||
"branch": "stable", | ||
"categories": ["NFT", "Swap", "YourAppCategory"], | ||
"currencies": "*", | ||
"content": { | ||
"shortDescription": { | ||
"en": "Desc" | ||
}, | ||
"description": { | ||
"en": "Desc" | ||
} | ||
}, | ||
"permissions": [], | ||
"domains": ["http://*"], | ||
"visibility": "complete" | ||
} | ||
``` | ||
<Callout emoji="💡"> | ||
For more informations regarding the setting up of a manifest, please refer to [the manifest page](/appendix/manifest) | ||
</Callout> | ||
|
||
### 10. **Importing Manifest in Ledger Live** | ||
|
||
Ensure Ledger Live Desktop is installed on your computer. Enable Developer mode in Ledger Live by navigating to **Settings** -> **About**, and clicking ten times on the Ledger Live version. This will reveal a new **Developer** section in the settings menu. | ||
|
||
- Enable **platform dev tools**. | ||
- Click on **Browse** next to **Add a local app** and select the manifest you created. | ||
|
||
Now you'll see a new row in the menu with the name of your Live App. You can now open and test your Live App within Ledger Live. | ||
|
||
--- | ||
|
||
This concludes the step-by-step guide to developing a Live App for Ledger Live from scratch. | ||
|
||
Have any questions or suggestions for improvement? Leave an issue in our repo or reach out to us through our Discord. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { FileTree } from 'nextra/components' | ||
|
||
# Building a Live App: A Step-by-Step Tutorial | ||
|
||
### 1. Introduction | ||
A Live App is a decentralized application (DApp) that interacts with Ledger Live, a software application used for managing crypto assets on Ledger hardware wallets. By creating a Live App, developers can provide users with seamless interactions with blockchain-based applications directly through Ledger Live. This tutorial will guide you through the process of building a Live App from scratch, utilizing the Ledger Wallet API Client to facilitate interactions with the Ledger Live environment. | ||
|
||
### 2. Setting up the Development Environment | ||
Before you begin building your Live App, we'll set up your development environment. This setup includes installing necessary tools and libraries that will assist in building, testing, and deploying your Live App. | ||
|
||
#### Scaffold a Next.js app | ||
First, scaffold a new Next.js app using the following command: | ||
|
||
```sh | ||
npx create-next-app my-app --typescript | ||
``` | ||
This will create a new Next.js project called my-app with TypeScript support. | ||
|
||
#### Node.js and npm: | ||
Ensure that you have Node.js and npm (Node Package Manager) installed on your computer. If not, download and install the latest LTS version of Node.js from the official website, which includes npm. | ||
|
||
#### Text Editor: | ||
Use a text editor of your choice. Popular choices include Visual Studio Code, Sublime Text, or Atom. | ||
|
||
#### Simulator: | ||
Install the Ledger Wallet API simulator for a mock environment to ease the development and testing phases. You can install the simulator library using npm: | ||
|
||
```sh | ||
npm install @ledgerhq/wallet-api-simulator | ||
``` | ||
|
||
The simulator provides a mock environment with predefined responses for different Wallet API actions, allowing you to test your Live App without interacting with the real Ledger Live application. | ||
|
||
### 3. Creating the Project Structure | ||
Now organize your project with a clear and manageable architecture. Here's a simple project structure to start with: | ||
|
||
<FileTree> | ||
<FileTree.Folder name="src" defaultOpen> | ||
<FileTree.Folder name="components"> | ||
<FileTree.File name="Header.tsx" /> | ||
<FileTree.File name="Footer.tsx" /> | ||
</FileTree.Folder> | ||
|
||
<FileTree.Folder name="hooks"> | ||
<FileTree.File name="useAccounts.tsx" /> | ||
<FileTree.File name="useSignTransaction.tsx" /> | ||
</FileTree.Folder> | ||
|
||
<FileTree.Folder name="utils"> | ||
</FileTree.Folder> | ||
|
||
<FileTree.Folder name="assets"> | ||
</FileTree.Folder> | ||
|
||
<FileTree.File name="App.tsx" /> | ||
</FileTree.Folder> | ||
|
||
<FileTree.Folder name="public"> | ||
<FileTree.File name="favicon.ico" /> | ||
<FileTree.File name="vercel.svg" /> | ||
</FileTree.Folder> | ||
|
||
<FileTree.File name="package.json" /> | ||
|
||
<FileTree.File name="tsconfig.json" /> | ||
</FileTree> | ||
|
||
|
||
- /src: This directory contains all your TypeScript/JavaScript files. | ||
|
||
- /components: This is where you’ll place your React components. | ||
|
||
- /hooks: This will hold custom hooks, including those for | ||
interacting with the Ledger Wallet API. | ||
|
||
- /utils: Any utility functions or constant values can be stored here. | ||
|
||
- /assets: Place images, icons, and other static files in this directory. | ||
|
||
- App.tsx: This is the main file where your React application is bootstrapped. | ||
|
||
- /public: This directory contains public assets like the index.html file. | ||
|
||
- package.json: This file holds various metadata relevant to your project. | ||
|
||
- tsconfig.json: This is your TypeScript configuration file if you're using TypeScript. | ||
|
||
Now that your development environment is set up, and you have a basic project structure in place, you are ready to start building your Live App. In the next section, we'll delve into configuring the Wallet API to establish a connection with Ledger Live. |
eae3598
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
wallet-api-wallet-api-tools – ./apps/wallet-api-tools
wallet-api-wallet-api-tools-ledgerhq.vercel.app
wallet-api-wallet-api-tools-git-main-ledgerhq.vercel.app
wallet-api-wallet-api-tools.vercel.app
eae3598
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
wallet-api – ./apps/docs
wallet-api-git-main-ledgerhq.vercel.app
wallet.api.live.ledger.com
wallet-api-ledgerhq.vercel.app