diff --git a/examples/ui-demo/src/components/small-cards/Transactions.tsx b/examples/ui-demo/src/components/small-cards/Transactions.tsx index 967e3abe00..35fb0695d1 100644 --- a/examples/ui-demo/src/components/small-cards/Transactions.tsx +++ b/examples/ui-demo/src/components/small-cards/Transactions.tsx @@ -1,8 +1,12 @@ import { ExternalLinkIcon } from "@/components/icons/external-link"; import { CheckCircleFilledIcon } from "@/components/icons/check-circle-filled"; import { LoadingIcon } from "@/components/icons/loading"; -import { TransactionType } from "@/hooks/useRecurringTransactions"; +import { + RECURRING_TXN_INTERVAL, + TransactionType, +} from "@/hooks/useRecurringTransactions"; import { cn } from "@/lib/utils"; +import { useEffect, useState } from "react"; export type loadingState = "loading" | "success" | "initial"; @@ -25,16 +29,32 @@ const Transaction = ({ externalLink, buyAmountUsdc, state, - secUntilBuy = 0, + timeToBuy, }: TransactionType & { className?: string }) => { + const [secUntilBuy, setSecUntilBuy] = useState(undefined); + + useEffect(() => { + if (state === "complete" || state === "initial" || !timeToBuy) { + return; + } + + const interval = setInterval(() => { + setSecUntilBuy(Math.ceil((timeToBuy - Date.now()) / 1000)); + }, 250); + + return () => clearInterval(interval); + }, [state, timeToBuy]); + const getText = () => { if (state === "initial") { return "Waiting..."; } if (state === "next") { - return secUntilBuy <= 0 + return secUntilBuy != null && secUntilBuy <= 0 ? "Waiting for previous transaction..." - : `Next buy in ${secUntilBuy} second${secUntilBuy === 1 ? "" : "s"}`; + : `Next buy in ${secUntilBuy ?? RECURRING_TXN_INTERVAL / 1000} second${ + secUntilBuy === 1 ? "" : "s" + }`; } if (state === "initiating") { return "Buying 1 ETH"; diff --git a/examples/ui-demo/src/hooks/useRecurringTransactions.ts b/examples/ui-demo/src/hooks/useRecurringTransactions.ts index 54e9634f38..fa8c3c4738 100644 --- a/examples/ui-demo/src/hooks/useRecurringTransactions.ts +++ b/examples/ui-demo/src/hooks/useRecurringTransactions.ts @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useState } from "react"; import type { BatchUserOperationCallData } from "@aa-sdk/core"; import { encodeFunctionData, @@ -33,8 +33,7 @@ export type TransactionType = { state: TransactionStages; buyAmountUsdc: number; externalLink?: string; - timeToBuy?: number; // timestamp when the txn will initiate - secUntilBuy?: number; // seconds until the txn will initiate + timeToBuy?: number; // timestamp when the txn should initiate }; export const initialTransactions: TransactionType[] = [ @@ -52,6 +51,8 @@ export const initialTransactions: TransactionType[] = [ }, ]; +export const RECURRING_TXN_INTERVAL = 10_000; + export interface UseRecurringTransactionReturn { isLoadingClient: boolean; cardStatus: CardStatus; @@ -103,36 +104,6 @@ export const useRecurringTransactions = ({ }); }; - // Handle the ticking of the timers. - useEffect(() => { - if ( - transactions.every( - (it) => it.state === "complete" || it.state === "initial" - ) - ) { - return; - } - - const interval = setInterval(() => { - setTransactions((prev) => - prev.map((txn) => - txn.state === "next" && txn.timeToBuy - ? { - ...txn, - secUntilBuy: Math.ceil((txn.timeToBuy - Date.now()) / 1000), - } - : txn - ) - ); - - if (transactions.every((it) => it.state === "complete")) { - clearInterval(interval); - } - }, 250); - - return () => clearInterval(interval); - }, [transactions]); - const handleTransaction = async (transactionIndex: number) => { if (!sessionKeyClient) { return handleError(new Error("no session key client")); @@ -146,8 +117,7 @@ export const useRecurringTransactions = ({ ? { ...txn, state: "next", - timeToBuy: Date.now() + 10_000, - secUntilBuy: 10, + timeToBuy: Date.now() + RECURRING_TXN_INTERVAL, } : txn ) @@ -311,7 +281,11 @@ export const useRecurringTransactions = ({ await Promise.all([ handleTransaction(i), ...(i < transactions.length - 1 - ? [new Promise((resolve) => setTimeout(resolve, 10_000))] + ? [ + new Promise((resolve) => + setTimeout(resolve, RECURRING_TXN_INTERVAL) + ), + ] : []), ]); }