Skip to main content

🎯 7. Check in the user

Finally, everything is ready and you can do a check-in for the user.

Add button for checking in​

  1. Go to the check-in.tsx file.

  2. Add states to manage the send transaction flow:

    • txHash: transaction hash received after successfully sending a transaction to Ronin.

    • isWaitTx: loading indicator when user sends their check-in transaction.

    • error: for unexpected cases.

    const [txHash, setTxHash] = useState<string>()
    const [isWaitTx, setIsWaitTx] = useState<boolean>(false)
    const [error, setError] = useState<string>()
  3. Add a button for users to check in. This button should be turned off when loading and isWaitTx. When the user clicks the button, it should call the handleCheckIn function.

    return (
    <div>
    {/* ALREADY DONE CODE */}

    {walletClient && (
    <button
    className="bg-sky-600 hover:bg-sky-700 text-white font-bold py-3 px-4 rounded-xl mt-2 disabled:opacity-50 tracking-wider"
    disabled={isCheckedIn || loading || isWaitTx}
    onClick={handleCheckIn}
    >
    {isWaitTx ? "Wait for transaction" : "Check In"}
    </button>
    )}
    </div>
    )

Send transaction to check in​

  1. Go to the check-in.tsx file.

  2. Change the loading status to true when the user clicks the button:

    const handleCheckIn = async () => {
    setTxHash(undefined)
    setIsWaitTx(true)
    }
  3. Before sending a transaction, you need to simulate it:

    • Are all parameters correct?

    • Does user have enough RON to execute the transaction?

    • Because eth_estimateGas only reads state from the blockchain, you should use Public Client to do it. You can learn more about eth_estimateGas in MetaMask documentation.

    • Call the checkIn function of the smart contract to do the check-in. The only argument is account.

    • Wrap this block in try catch to handle errors.

    const handleCheckIn = async () => {
    setTxHash(undefined)
    setIsWaitTx(true)

    try {
    const { txRequest } = await web3PublicClient.simulateContract({
    account,
    address: CHECK_IN_ADDRESS,
    abi: CHECK_IN_ABI,
    functionName: "checkIn",
    args: [account],
    })
    } catch (error) {
    console.log(error)

    setError("Could NOT send transaction - check your console for future details.")
    setTxHash(undefined)
    setIsWaitTx(false)
    }
    }
  4. Send a transaction and get the transaction hash:

    • When sending a transaction, because you need the user to sign it in their wallet, you should use Wallet Client to do this action.
    • Use writeContract function on the wallet client.
    • All you need is txRequest that you received from the simulateContract step.
    • Remember to use setTxHash to display it to the user.
    const txHash = await walletClient.writeContract(request)
    setTxHash(txHash)
  5. Display the transaction hash or error to the user:

    return (
    <div>
    {/* ALREADY DONE CODE */}

    <div className="flex flex-col gap-2 mt-8">
    <button
    className="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-xl mt-2 disabled:opacity-50"
    disabled={isCheckedIn || loading || isWaitTx}
    onClick={handleCheckIn}
    >
    {isWaitTx ? "Wait for transaction" : "Check In"}
    </button>

    {txHash && (
    <>
    <p className="font-semibold text-green-600">Send successfully!</p>
    <a
    className="text-blue-700 hover:text-blue-800"
    href={`https://saigon-app.roninchain.com/tx/${txHash}`}
    >
    Check your transaction here
    </a>
    </>
    )}

    {error && <p className="text-red-600">{error}</p>}
    </div>
    </div>
    )

Refresh check-in status​

At the step Send transaction to check in, you successfully sent the transaction but the user still receives the "Please do check in" status. This happens due to the following reasons:

  • The user only sends the transaction, but the blockchain hasn't yet processed it.
  • The Ronin chain often takes 3-4 seconds to process a transaction.

To handle this case in your app, wait for the transaction to process, and then refresh the check-in status.

  1. Go to check-in.tsx file.

  2. After sending the transaction, use the waitForTransactionReceipt function from Public Client to get the receipt.

    const receipt = await web3PublicClient.waitForTransactionReceipt({
    hash: txHash,
    })
  3. If the transaction has a success status, refetch the check-in information and finish the check-in flow.

    if (receipt.status === "success") {
    refetchCheckedIn()
    setError(undefined)
    setIsWaitTx(false)

    return
    }

    throw "Transaction reverted!"

Full flow​