Skip to content

Working with Predicates

This guide builds on the Creating a Fuel dApp guide. Once you've gotten the dApp there up and running, then you can continue here via clicking the Predicate Example link. We will modify the predicate we created in the previous guide. The final result will look like this:

End result of this guide

You can also check it live, deployed to the Testnet:

Adding a Configurable pin

The current predicate functionality we have is a simple one that checks if the user has a pin. We will modify this predicate to accept a configurable pin. This will allow the user to set their own pin.

  1. Modifying the Predicate Contract

The first step is to modify the predicate contract to accept a configurable pin. We will use the configurable keyword to create an updatable constant to store the pin. We will also modify the main function to check this constant instead of a hardcoded pin.

rust
predicate;

configurable {
    PIN: u64 = 1337,
}

fn main(pin: u64) -> bool {
    return PIN == pin;
}
See code in context
  1. Modifying the Frontend

We will now add new button to the frontend that will update the pin in the predicate when clicked. To do this, we will modify the ./src/components/Predicate.tsx file.

We will add a function called changePin, which will use the current pin in state to update the pin in the predicate as well as transfer 1000 to the predicate.

ts
const changePin = async () => {
  if (!wallet || !predicate) return;
  setIsLoading(true);

  try {
    const configurableConstants = { PIN: bn(predicatePin) };
    const newPredicate = new TestPredicate({
      provider: wallet.provider,
      data: [configurableConstants.PIN],
      configurableConstants,
    });

    const tx = await wallet.transfer(newPredicate.address, bn(2_000_000));
    transactionSubmitNotification(tx.id);
    await tx.waitForResult();
    transactionSuccessNotification(tx.id);
  } catch (error) {
    console.error(error);
    errorNotification(
      "Error changing pin.",
    );
  }
  setIsLoading(false);
  refetch();
};
See code in context

It would also be useful to change the placeholder text.

tsx
<input
  type="text"
  value={predicatePin}
  onChange={(e) => setPredicatePin(e.target.value)}
  className="w-1/2 bg-gray-800 rounded-md px-2 py-1 mr-3 truncate font-mono"
  placeholder="Enter current or new pin"
/>

Finally, we will add a button that calls the changePin function when clicked.

tsx
<Button onClick={changePin} className="w-full" disabled={isLoading}>
  Change Pin
</Button>

Congratulations! That's all. You should now be able to see the modified predicate dApp running at http://localhost:5173 with our newly added change pin functionality.

You can find the complete source code of the dApp we built here.

Next Steps

  • Now that you have a predicate dApp running and have the npm create fuels workflow powering you, you can start building more complex dApps using the Fuel Stack. A good place to start for ideas and reference code is the Sway Applications Repo.

  • If you have any questions or need help, feel free to reach out to us on the Official Fuel Forum.

  • If you want to learn more about the Fuel Stack, check out the Fuel Docs.