diff --git a/docs/recipes/WaitTxApprovalReceiptLaunchNextTx.md b/docs/recipes/WaitTxApprovalReceiptLaunchNextTx.md index 17789de..df6a6a1 100644 --- a/docs/recipes/WaitTxApprovalReceiptLaunchNextTx.md +++ b/docs/recipes/WaitTxApprovalReceiptLaunchNextTx.md @@ -1,144 +1,127 @@ --- sidebar_position: 3 -title: Wait for TxReceipt to Send a Second Tx -description: Learn how to wait for a transaction receipt before sending a second transaction in a multi-step process. +title: Wait for TxReceipt to send next transaction +description: Learn how to wait for TxReceipt before sending a new transaction in a multi-step process. --- # Wait for Transaction Receipt to Send a Second Transaction This recipe shows how to create a multi-step transaction process where you wait for the receipt of the first transaction before sending a second transaction. -## Before You Begin +Here is the full code, which we will be implementing in the guide below: -Before you proceed with this recipe, make sure you have the [required dependencies installed](/quick-start/installation), and you're familiar with setting up your [Ethereum development environment](/quick-start/environment). - -In this recipe you will use a few hooks: - -- [usePublicClient](https://wagmi.sh/react/hooks/usePublicClient) and [useContractWrite](https://wagmi.sh/react/hooks/useContractWrite) from wagmi. -- [useScaffoldContractWrite](/hooks/useScaffoldContractWrite) and [useDeployedContractInfo](/hooks/useDeployedContractInfo) Scaffold ETH-2 hooks. - -You'll also use [AddressInput](/components/AddressInput) and [InputBase](/components/InputBase) Scaffold ETH-2 components, [ParseEther viem utility](https://viem.sh/docs/utilities/parseEther.html#parseether) and erc721ABI from wagmi. We recommend checking out the details of these hooks, components and utils before start implementing this recipe. - -## Implementation - -### Step 1: Create Your Component - -Begin by creating a new component, which we'll name "SellNFT.tsx". This component will allow users to perform a multi-step ERC721 approve+listing process for selling a NFT, similar to the ERC20 approve pattern. - -Import the necessary libraries and components: - -```tsx +```tsx title="components/SellNFT.tsx" import { useState } from "react"; -import type { NextPage } from "next"; import { parseEther } from "viem"; import { erc721ABI, useContractWrite, usePublicClient } from "wagmi"; -import { AddressInput, InputBase } from "~~/components/scaffold-eth/Input"; import { useDeployedContractInfo, useScaffoldContractWrite } from "~~/hooks/scaffold-eth"; -``` - -Define the functional component "SellNFT" which will be used to create the user interface for the multi-step transaction process: +import { AddressInput, InputBase } from "~~/components/scaffold-eth/Input"; -```tsx -const SellNFT: NextPage = () => { - // Your component code will go here. -}; -``` +export const SellNFT = () => { + const [address, setAddress] = useState(""); + const [tokenId, setTokenId] = useState(""); + const [price, setPrice] = useState(""); -### Step 2: Initialize Hooks for Contract Interaction + const publicClient = usePublicClient(); -Initialize the necessary hooks for interacting with the smart contract. In this example, we'll use two hooks: `useContractWrite` and `useScaffoldContractWrite`. + const { data: NftMarketplace } = useDeployedContractInfo("NftMarketplace"); -```tsx -const [address, setAddress] = useState(""); -const [tokenId, setTokenId] = useState(""); -const [price, setPrice] = useState(""); - -const publicClient = usePublicClient(); - -const { data: NftMarketplace } = useDeployedContractInfo("NftMarketplace"); - -const approveTx = useContractWrite({ - address: address, - abi: erc721ABI, - functionName: "approve", - args: [NftMarketplace?.address as string, BigInt(tokenId)], -}); - -const listNftTx = useScaffoldContractWrite({ - contractName: "NftMarketplace", - functionName: "listItem", - args: [address, BigInt(tokenId), parseEther(price)], -}); -``` + const approveTx = useContractWrite({ + address: address, + abi: erc721ABI, + functionName: "approve", + args: [NftMarketplace?.address as string, BigInt(tokenId)], + }); -### Step 3: Create the Multi-Step Transaction Process + const listNftTx = useScaffoldContractWrite({ + contractName: "NftMarketplace", + functionName: "listItem", + args: [address, BigInt(tokenId), parseEther(price)], + }); -Design the user interface to allow users to perform a multi-step transaction process. In this example, we've created a form for selling a NFT: + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + const approveHash = await approveTx?.writeAsync(); + await publicClient.waitForTransactionReceipt(approveHash); + await listNftTx?.writeAsync(); + }; -```tsx -return ( -
-

Sell Your NFT

-
-
-
- - setAddress(val)} /> -
-
- - setTokenId(val)} /> -
-
- - setPrice(val)} /> -
-
- -
-
+ return ( +
+

Sell Your NFT

+
+
+
+ + setAddress(val)} /> +
+
+ + setTokenId(val)} /> +
+
+ + setPrice(val)} /> +
+
+ +
+
+
-
-); + ); +}; ``` -### Step 4: Implement Multi-Step Transaction Logic +## Implementation -Add logic to handle the multi-step transaction process. In this example, we submit the first transaction to approve the marketplace contract address to transfer our NFT. Then we wait for its receipt before proceeding to list the NFT for sale: +### Step 1: Set Up Your Component -```tsx -const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - const approveHash = await approveTx?.writeAsync(); - await publicClient.waitForTransactionReceipt(approveHash); - await listNftTx?.writeAsync(); +Create a new component in the "components" folder. This component will allow users to perform a multi-step `ERC721` approve+listing process for selling a NFT, similar to the `ERC20` approve pattern. + +```tsx title="components/SellNFT.tsx" +export const SellNFT = () => { + return ( +
+

Sell Your NFT

+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ ); }; ``` -### Step 5: Test and Deploy - -Test your multi-step transaction process to ensure that it correctly waits for the receipt of the first transaction before proceeding with the second. - -## Conclusion - -By following these steps, you've created a multi-step transaction process that waits for the receipt of the first transaction before sending the second. This behaviour will be useful for many different types of smart contract interactions, like approving a contract to spend your tokens, or approving a contract to transfer your NFTs. +### Step 2: Initialize Hooks for Contract Interaction -## Full Recipe Code +Initialize the necessary hooks for interacting with the smart contract. In this recipe, we're using: -
- Here's the complete code for the "SellNFT" component: +- [usePublicClient](https://wagmi.sh/react/hooks/usePublicClient) and [useContractWrite](https://wagmi.sh/react/hooks/useContractWrite) from wagmi. +- [useScaffoldContractWrite](/hooks/useScaffoldContractWrite) and [useDeployedContractInfo](/hooks/useDeployedContractInfo) Scaffold ETH-2 hooks. ```tsx +// highlight-start import { useState } from "react"; -import type { NextPage } from "next"; import { parseEther } from "viem"; import { erc721ABI, useContractWrite, usePublicClient } from "wagmi"; -import { AddressInput, InputBase } from "~~/components/scaffold-eth/Input"; import { useDeployedContractInfo, useScaffoldContractWrite } from "~~/hooks/scaffold-eth"; -const SellNFT: NextPage = () => { +export const SellNFT = () => { const [address, setAddress] = useState(""); const [tokenId, setTokenId] = useState(""); const [price, setPrice] = useState(""); @@ -159,43 +142,104 @@ const SellNFT: NextPage = () => { functionName: "listItem", args: [address, BigInt(tokenId), parseEther(price)], }); - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - const approveHash = await approveTx?.writeAsync(); - await publicClient.waitForTransactionReceipt(approveHash); - await listNftTx?.writeAsync(); - }; - + // highlight-end return (

Sell Your NFT

-
+
- setAddress(val)} />
- setTokenId(val)} />
- setPrice(val)} />
- +
); }; - -export default SellNFT; ``` -
+### Step 3: Add all the inputs and submit logic to your form + +Create `handleSubmit` logic with the multi-step listing process, waiting for the approval transaction receipt in order to list the NFT. Once you're done with the logic, call it when users submit the form. + +Add the inputs to your form, using [AddressInput](/components/AddressInput) and [InputBase](/components/InputBase) Scaffold ETH-2 components. + +```tsx +import { useState } from "react"; +import { parseEther } from "viem"; +import { erc721ABI, useContractWrite, usePublicClient } from "wagmi"; +import { useDeployedContractInfo, useScaffoldContractWrite } from "~~/hooks/scaffold-eth"; +// highlight-start +import { AddressInput, InputBase } from "~~/components/scaffold-eth/Input"; +// highlight-end + +export const SellNFT = () => { + const [address, setAddress] = useState(""); + const [tokenId, setTokenId] = useState(""); + const [price, setPrice] = useState(""); + + const publicClient = usePublicClient(); + + const { data: NftMarketplace } = useDeployedContractInfo("NftMarketplace"); + + const approveTx = useContractWrite({ + address: address, + abi: erc721ABI, + functionName: "approve", + args: [NftMarketplace?.address as string, BigInt(tokenId)], + }); + + const listNftTx = useScaffoldContractWrite({ + contractName: "NftMarketplace", + functionName: "listItem", + args: [address, BigInt(tokenId), parseEther(price)], + }); + + // highlight-start + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + const approveHash = await approveTx?.writeAsync(); + await publicClient.waitForTransactionReceipt(approveHash); + await listNftTx?.writeAsync(); +}; +// highlight-end + +return ( +
+

Sell Your NFT

+
+
+
+ + setAddress(val)} /> +
+
+ + setTokenId(val)} /> +
+
+ + setPrice(val)} /> +
+
+ +
+
+
+
+ // highlight-end +); +```