Read accounts and sign a transaction
In this tutorial, we will read accounts from the Wallet API and sign one Ethereum transaction. By the end, App.tsx will list the accounts and show a signature response.
This page continues Configure the Wallet API.
6. Read accounts
Create src/hooks/useAccounts.tsx. The useAccounts hook from @ledgerhq/wallet-api-client-react returns the accounts, a loading flag, and an error.
// 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;We can call useUserAccounts from a component. The list is empty until the transport is connected.
7. Sign an Ethereum transaction
Create src/hooks/useSignTransaction.tsx. useRequestAccount selects an account. useSignTransaction asks the signer to sign the transaction we pass in.
// 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. Show the accounts and the signature
Create src/App.tsx. It renders the accounts from useUserAccounts and a button that calls handleSignTransaction.
// 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;We have an app that lists accounts and requests one signature. The recipient in the sample is still 0xRecipientAddressHere, and the nonce is 0. We replace both before a signature can be accepted. Next: Load the manifest.