Now for the most important part of all DApps: the state-changing transactions. This is where money moves, where tokens are minted, and value passes.
If you recall from our smart contract, we want to mint some tokens by calling the purchaseMint function with some native currency. So we're going to need:
A text input that lets the user specify how much value to enter
A button that lets the user initiate the transaction signature
Let's create a new component called MintingComponent in a new file called MintingComponent.js. First, we'll tackle the text input, which will require us to add the logic to store the number of tokens to mint and a text field element.
import { useState } from 'react';
import { useContractFunction, useEthers, MoonbaseAlpha } from '@usedapp/core';
import { Button, CircularProgress, TextField, Grid } from '@mui/material';
import { utils } from 'ethers';
export default function MintingComponent({ contract }) {
const [value, setValue] = useState(0);
const textFieldStyle = { marginBottom: '16px' };
return (
<>
<Grid item xs={12}>
<TextField
type='number'
onChange={(e) => setValue(e.target.value)}
label='Enter value in DEV'
variant='outlined'
fullWidth
style={textFieldStyle}
/>
</Grid>
{/* This is where we'll add the button */}
</>
);
}
Next, we'll need to create the button to send the transaction, which will call the purchaseMint of our contract. Interacting with the contract will be a bit more difficult since you're likely not as familiar with it. We've already done a lot of setup in the previous sections, so it doesn't actually take too much code:
The user's account information is being retrieved via useEthers, which can be done because useDApp provides this information throughout the entire project
The useContractFunction hook from useDApp is used to create a function, send, that will sign and send a transaction that calls the purchaseMint function on the contract defined by the contract object
Another function, handlePurchaseMint, is defined to help inject the native gas value defined by the TextField component into the send function. It first checks if the user has their wallet connected to Moonbase Alpha, and if not, it prompts the user to switch networks
A helper constant will determine whether or not the transaction is still in the Mining phase, that is, it hasn't finished
Now let's look at the visual component. The button will call the handlePurchaseMint on press, which makes sense. The button will also be disabled while the transaction happens and if the user hasn't connected to the DApp with their wallet (when the account value isn't defined).
This code essentially boils down to using the useContractFunction hook in conjunction with the contract object, which is a lot simpler than what it does under the hood! Let's add this component to the main App.js file.