🔍 5. Get the check-in status of the user
To do a daily check-in for a user, you need to know whether they have already checked in today. You can do this using the address that you retrieved from Ronin Waypoint at the previous step.
Create public web3 client
In the app
directory, a create web3-client.ts
file:
import { createPublicClient, http } from "viem"
import { saigon } from "viem/chains"
export const web3PublicClient = createPublicClient({
transport: http(),
chain: saigon,
})
The web3PublicClient
enables you to request information from the Ronin blockchain. For an easier and more type-safe way to interact with Ethereum, we recommend using viem.
Create placeholder file for check-in logic
-
Create a
check-in.tsx
component for the check-in UI:import { FC, useState } from "react"
import { Address } from "viem"
type Props = {
account: Address
}
export const CheckIn: FC<Props> = ({ account }) => {
return (
<div>
Placeholder
</div>
)
} -
Create
use-is-checked-in.ts
to hold a hook that helps you get the check-in status of a specific address:import { useState } from "react"
import { Address } from "viem"
export const useIsCheckedIn = (currentAddress: Address) => {
const [missed, setMissed] = useState<boolean | undefined>()
const [loading, setLoading] = useState<boolean>(false)
return {
data: !missed,
loading,
}
}
Get the check-in status
Go to use-is-checked-in.ts
file:
const fetchIsCheckedIn = async () => {
setLoading(true)
setMissed(undefined)
try {
const isMissed = await web3PublicClient.readContract({
address: CHECK_IN_ADDRESS,
abi: CHECK_IN_ABI,
functionName: "isMissedCheckIn",
args: [currentAddress],
})
setMissed(isMissed)
setLoading(false)
return
} catch (error) {
/* empty */
}
setMissed(undefined)
setLoading(false)
}
-
In this function, because you get public data from the blockchain, you should use
Public Client
. -
Just pass the right
functionName
andargs
, letting viem handle the rest. -
Remember to use
setMissed
for data update andsetLoading
for loading state. -
After that, call
fetchIsCheckedIn
inuseEffect
. -
Return
fetchIsCheckedIn
as a refetch function because you need refetch status after the user checks in.useEffect(() => {
fetchIsCheckedIn()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [currentAddress])
return {
data: !missed,
loading,
refetch: fetchIsCheckedIn,
}
Build the UI to show check-in status
-
Go to the
check-in.tsx
file. -
Consume
useIsCheckedIn
hook:const { data: isCheckedIn, loading, refetch: refetchCheckedIn } = useIsCheckedIn(account)
-
Display the check-in status in the UI:
return (
<div>
<div className="font-semibold tracking-wider">
{loading ? (
<div className="text-cyan-600">Loading...</div>
) : (
<>
{isCheckedIn ? (
<div className="text-amber-600">You are already checked in for today.</div>
) : (
<div className="text-emerald-600">Please check in now!</div>
)}
</>
)}
</div>
</div>
) -
Go to the
page.tsx
file. -
Render
CheckIn
component if the account is available:return (
<main className="flex flex-col items-start min-h-screen gap-4 p-24">
{/* OLD CODE */}
{account && <CheckIn account={account} />}
</main>
)
At this step, you successfully implemented the get check-in status flow. The UI should look like this: