Bonfire is the interview exercise for Frontend-related engineer roles at APWine.
It is a simple application built with Next.js, Tailwind CSS, web3-react and TanStack Query among other technologies. No knowledge of Web3 is required to complete the exercise.
The Figma file for the application can be found on this page.
You are an adventurer on a journey to complete three different quests. The application consists of a single page that displays the list of available quests. You can complete a quest by clicking on the "Start" button. To complete quests, you will need to have enough energy, which is stored in a smart contract on the blockchain (think of it as a database + API on Ethereum). You can refill your energy by resting at the Bonfire. Any action you take will be a transaction on the blockchain.
The application has pieces of code missing. Your goal is to complete the application by filling in the missing pieces of code. You can find the missing pieces by searching for the following comments:
/* TODO: ... */
You will need:
- Node.js
- Yarn
- An Alchemy API key - see here for instructions on how to get one
- A Web3 wallet (e.g. MetaMask) connected to the Goerli test network, along with some test ETH
- Clone the repository:
git clone https://github.com/APWine/frontend-exercise-public && cd frontend-exercise-public
- Install dependencies:
yarn
- Copy the
.env.example
file to.env
and fill in your Alchemy API key - Generate contract typings:
yarn gen:typechain
- Start the development server:
yarn dev
The whole project should take you about an hour to complete. For each exercise, you are free to create any additional types, props, components, files, etc. as you see fit.
Implement the Button component in components/Button.tsx
. The props are already defined, but the component is not implemented. You should take reference from the Figma design.
Take a look at how the useWallet
hook works and display either the connect wallet page or the home page in pages/index.tsx
.
Now is time to load data from the blockchain. Implement the queries in useCompletedQuestsQuery.ts
, useEnergyLeftQuery.ts
, and useQuestsQuery.ts
.
Hints:
- Some data, such as completed quests, is associated to a specific user/account. You'll need to handle the scenario where the user changes their account in their wallet.
- You can use the
useBonfire
hook to retrieve the smart contract. It contains all methods you need to interact with it. - For the
useCompletedQuests
query, you will need to do multiple calls to the smart contract. Fortunately, you can batch all calls into one using aPromise.all
containing all fetch promises, then return the entire array.
Implement the BonfireRestButton
component in components/BonfireRestButton.tsx
. It should call the rest
method on the smart contract when clicked. If the user does not need energy, the button should be disabled.
Hints:
- For success and error handling, you can use the
toast.promise
method from react-hot-toast, which takes a promise. - You will need to connect the bonfire contract to the user signer. You can find the signer in
useWallet
and connect the contract to it using.connect(signer)
. - A success message should display when the transaction is confirmed on the blockchain. You can use
tx.wait()
to wait for the transaction to be confirmed. Thetx
object is returned when calling smart contract methods.
Now you're on your own! Combine all your knowledge to finish the application. The final step is to implement the QuestCard
component in components/QuestCard.tsx
. It should display the quest data and allow the user to start the quest. When the user clicks on the "Start" button, the completeQuest
method should be called on the smart contract. Depending on whether the quest is completed and whether the user has enough energy, the card should change its background color and hide the "Start" button.
Proceed with success and error handling in the same way as the previous step.
If you've completed the exercise, you can try to implement the following:
- Animations
- Custom styling
- Code refactoring. How would you make it more efficient?
Please submit your solution as a link to a public GitHub repository. If you have any questions, please contact us at [email protected].