The useSimulateContract hook
The useSimulateContract hook simulates and validates a contract interaction without actually sending a transaction to the blockchain. Using it allows you to detect and respond to potential errors before the user tries to send a transaction.
Objectives
By the end of this guide you should be able to:- Implement wagmi’s useSimulateContractanduseWriteContractto send transactions to a smart contract
- Configure the options in useSimulateContractanduseWriteContract
- Call a smart contract function on-demand using the write function from useWriteContract, with arguments and a value
Refining the Claim Component
In the previous step-by-step, you useduseWriteContract to set up a hook you can use to call the claim function in your smart contract when the user clicks a button. The component works well enough, but it can take a long time for the wallet to pop up, particularly if there is network congestion. You also have no way of responding to a problem with the transaction inputs until after the user tries to initiate a transaction.
Using useSimulateContract
The useSimulateContract can be used in partnership with useWriteContract. To do so, you set up the transaction parameters in useSimulateContract, then use the data?.request returned by it as an argument in the call to write to the contract. Modify your TokenInfo component to test it:
undefined.
alert is triggered on load if you’re signed in with an address that has already claimed tokens. You’ll also see that the button is disabled, as though the user had clicked it and a transaction is loading in the wallet.
Making Adjustments
The reason for this is a subtle difference in howuseWriteContract and useSimulateContract work.
In the last step-by-step, you saw how viem runs a simulation of the transaction when the write function is called. useSimulateContract eagerly runs this simulation and updates it’s variables.
You’ll need to make some modifications for it to work. The claimIsError variable is being triggered when the data for the call is simulated, not when the call has settled. As a result, it immediately generates the error, and triggers the alert without requiring the user to click the button.
You can solve this a number of ways, including simply not rendering the button if the user has already claimed. You could also modify the code, and combine it with isError, to share this information to the user.
Conclusion
In this step-by-step, you updated your app to use theuseSimulateContract hook to provide a speedier wallet interaction for your users. You’ve also learned how you can predict and respond to potential errors without the user needing to attempt to send a transaction. You could use this functionality to let them know a username is already taken, a bid amount is not large enough, or an item is no longer available.