diff --git a/front/src/app/api/users/[id]/txs/route.ts b/front/src/app/api/users/[id]/txs/route.ts
deleted file mode 100644
index 9afc901..0000000
--- a/front/src/app/api/users/[id]/txs/route.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-import { ENTRYPOINT_ADDRESS, FACTORY_ABI, FACTORY_ADDRESS, PUBLIC_CLIENT } from "@/constants";
-import { Hex, stringify } from "viem";
-
-export async function GET(_req: Request, { params }: { params: { id: Hex } }) {
- const { id } = params;
-
- const user = await PUBLIC_CLIENT.readContract({
- address: FACTORY_ADDRESS,
- abi: FACTORY_ABI,
- functionName: "getUser",
- args: [BigInt(id)],
- });
-
- const latestBlock = await PUBLIC_CLIENT.getBlock();
-
- const logs = await PUBLIC_CLIENT.getLogs({
- address: ENTRYPOINT_ADDRESS,
- event: {
- inputs: [
- {
- internalType: "bytes32",
- name: "userOpHash",
- type: "bytes32",
- indexed: true,
- },
- {
- internalType: "address",
- name: "sender",
- type: "address",
- indexed: true,
- },
- {
- internalType: "address",
- name: "paymaster",
- type: "address",
- indexed: true,
- },
- {
- internalType: "uint256",
- name: "nonce",
- type: "uint256",
- indexed: false,
- },
- {
- internalType: "bool",
- name: "success",
- type: "bool",
- indexed: false,
- },
- {
- internalType: "uint256",
- name: "actualGasCost",
- type: "uint256",
- indexed: false,
- },
- {
- internalType: "uint256",
- name: "actualGasUsed",
- type: "uint256",
- indexed: false,
- },
- ],
- type: "event",
- name: "UserOperationEvent",
- anonymous: false,
- },
- fromBlock: latestBlock.number - BigInt(2000),
- toBlock: latestBlock.number,
- args: { sender: user.account },
- });
-
- return Response.json(JSON.parse(stringify({ logs })));
-}
diff --git a/front/src/app/layout.tsx b/front/src/app/layout.tsx
index 60b4013..a020490 100644
--- a/front/src/app/layout.tsx
+++ b/front/src/app/layout.tsx
@@ -7,7 +7,6 @@ import { SmartWalletProvider } from "@/libs/smart-wallet/SmartWalletProvider";
import { ModalProvider } from "@/providers/ModalProvider";
import { BalanceProvider } from "@/providers/BalanceProvider";
import { MeProvider } from "@/providers/MeProvider";
-import { TransactionProvider } from "@/providers/TransactionProvider";
import { Metadata } from "next";
import { ModalOnWCEvent } from "@/libs/wallet-connect/ModalOnWCEvent";
@@ -36,21 +35,19 @@ export default function RootLayout({ children }: { children: React.ReactNode })
-
-
-
-
-
-
-
- {children}
-
-
-
-
-
-
-
+
+
+
+
+
+
+ {children}
+
+
+
+
+
+
diff --git a/front/src/components/Address/index.tsx b/front/src/components/Address/index.tsx
index 3a2c182..056aaf1 100644
--- a/front/src/components/Address/index.tsx
+++ b/front/src/components/Address/index.tsx
@@ -25,6 +25,7 @@ export default function Address(props: Props) {
setTimeout(() => setIsCopied(false), 1000);
}}
style={{ ...props.style, display: "flex", alignItems: "center", gap: "6px" }}
+ size={"3"}
>
{me?.account.slice(0, 6)}...{me?.account.slice(-4)}
diff --git a/front/src/components/Balance/index.tsx b/front/src/components/Balance/index.tsx
index ea6b3d0..ae0ccce 100644
--- a/front/src/components/Balance/index.tsx
+++ b/front/src/components/Balance/index.tsx
@@ -5,7 +5,7 @@ import { Flex, Text } from "@radix-ui/themes";
import { CSSProperties, useEffect } from "react";
const css: CSSProperties = {
- padding: "2.5rem 0",
+ padding: "4rem 0",
};
export default function Balance() {
diff --git a/front/src/components/History/index.tsx b/front/src/components/History/index.tsx
index 8b27896..5926536 100644
--- a/front/src/components/History/index.tsx
+++ b/front/src/components/History/index.tsx
@@ -1,57 +1,33 @@
"use client";
-import { useTransaction } from "@/providers/TransactionProvider";
-import { Badge, Box, Button, Flex, Link, Separator, Text } from "@radix-ui/themes";
-import { Log } from "viem";
+import { Button, Flex, Callout } from "@radix-ui/themes";
+import { useMe } from "@/providers/MeProvider";
+import { ArrowRightIcon } from "@radix-ui/react-icons";
+import LogoAnimatedLight from "../LogoAnimatedLight";
export default function History() {
- const { loading, txs, getLastTxs, unwatchLogs } = useTransaction();
-
- if (loading)
- return (
-
- Fetching latest transactions...
-
- );
+ const { me } = useMe();
return (
-
-
-
- History
-
-
-
-
-
- {!loading &&
- Array.isArray(txs) &&
- txs.map((tx: Log) => {
- return (
-
-
-
-
- {tx?.transactionHash?.toString().slice(0, 4)}...
- {tx?.transactionHash?.toString().slice(-4)}
-
-
-
- {(tx as unknown as { args: { status: boolean } }).args.status}
-
- {(tx as unknown as { args: { success: boolean } })?.args.success ? (
- Complete
- ) : (
- Failed
- )}
-
-
- );
- })}
+
+
+
+ You smart contract wallet is deployed during the first transaction that you make. You can
+ still receive tokens and ETH on your smart contract wallet address in the meantime.
+
+
+
-
+
);
}
diff --git a/front/src/components/HomePage/index.tsx b/front/src/components/HomePage/index.tsx
index 0fb8c59..96710ef 100644
--- a/front/src/components/HomePage/index.tsx
+++ b/front/src/components/HomePage/index.tsx
@@ -7,6 +7,7 @@ import Balance from "../Balance";
import NavBar from "../NavBar";
import History from "../History";
import TopBar from "../TopBar";
+import LogoAnimated from "../LogoAnimated";
export default function Home() {
const { me, isMounted } = useMe();
@@ -15,10 +16,12 @@ export default function Home() {
if (me) {
return (
-
-
-
-
+
+
+
+
+
+
);
diff --git a/front/src/components/LogoAnimatedLight/index.tsx b/front/src/components/LogoAnimatedLight/index.tsx
new file mode 100644
index 0000000..963f7ec
--- /dev/null
+++ b/front/src/components/LogoAnimatedLight/index.tsx
@@ -0,0 +1,75 @@
+import { CSSProperties, useRef, useState } from "react";
+import "./logo-animated.css";
+
+type Props = {
+ style?: CSSProperties;
+};
+
+export default function LogoAnimatedLight({ style }: Props) {
+ const [increment, setIncrement] = useState(0);
+
+ return (
+
+ );
+}
diff --git a/front/src/components/LogoAnimatedLight/logo-animated.css b/front/src/components/LogoAnimatedLight/logo-animated.css
new file mode 100644
index 0000000..d3dd35e
--- /dev/null
+++ b/front/src/components/LogoAnimatedLight/logo-animated.css
@@ -0,0 +1,464 @@
+/***************************************************
+ * Generated by SVG Artista on 11/17/2023, 9:24:10 AM
+ * MIT license (https://opensource.org/licenses/MIT)
+ * W. https://svgartista.net
+ **************************************************/
+
+ @-webkit-keyframes animate-svg-stroke-1 {
+ 0% {
+ stroke-dashoffset: 2868.76611328125px;
+ stroke-dasharray: 2868.76611328125px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 2868.76611328125px;
+ }
+}
+
+@keyframes animate-svg-stroke-1 {
+ 0% {
+ stroke-dashoffset: 2868.76611328125px;
+ stroke-dasharray: 2868.76611328125px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 2868.76611328125px;
+ }
+}
+
+@-webkit-keyframes animate-svg-fill-1 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill:var(--accent-11);
+ }
+}
+
+@keyframes animate-svg-fill-1 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill:var(--accent-11);
+ }
+}
+
+.svg-elem-1 {
+ -webkit-animation: animate-svg-stroke-1 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0s both,
+ animate-svg-fill-1 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.8s both;
+ animation: animate-svg-stroke-1 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0s both,
+ animate-svg-fill-1 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.8s both;
+}
+
+@-webkit-keyframes animate-svg-stroke-2 {
+ 0% {
+ stroke-dashoffset: 2868.76611328125px;
+ stroke-dasharray: 2868.76611328125px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 2868.76611328125px;
+ }
+}
+
+@keyframes animate-svg-stroke-2 {
+ 0% {
+ stroke-dashoffset: 2868.76611328125px;
+ stroke-dasharray: 2868.76611328125px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 2868.76611328125px;
+ }
+}
+
+@-webkit-keyframes animate-svg-fill-2 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+@keyframes animate-svg-fill-2 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+.svg-elem-2 {
+ -webkit-animation: animate-svg-stroke-2 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.01s both,
+ animate-svg-fill-2 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.81s both;
+ animation: animate-svg-stroke-2 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.01s both,
+ animate-svg-fill-2 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.81s both;
+}
+
+@-webkit-keyframes animate-svg-stroke-3 {
+ 0% {
+ stroke-dashoffset: 7424.7177734375px;
+ stroke-dasharray: 7424.7177734375px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 7424.7177734375px;
+ }
+}
+
+@keyframes animate-svg-stroke-3 {
+ 0% {
+ stroke-dashoffset: 7424.7177734375px;
+ stroke-dasharray: 7424.7177734375px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 7424.7177734375px;
+ }
+}
+
+@-webkit-keyframes animate-svg-fill-3 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+@keyframes animate-svg-fill-3 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+.svg-elem-3 {
+ -webkit-animation: animate-svg-stroke-3 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.02s both,
+ animate-svg-fill-3 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.8200000000000001s both;
+ animation: animate-svg-stroke-3 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.02s both,
+ animate-svg-fill-3 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.8200000000000001s both;
+}
+
+@-webkit-keyframes animate-svg-stroke-4 {
+ 0% {
+ stroke-dashoffset: 1231.14892578125px;
+ stroke-dasharray: 1231.14892578125px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 1231.14892578125px;
+ }
+}
+
+@keyframes animate-svg-stroke-4 {
+ 0% {
+ stroke-dashoffset: 1231.14892578125px;
+ stroke-dasharray: 1231.14892578125px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 1231.14892578125px;
+ }
+}
+
+@-webkit-keyframes animate-svg-fill-4 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+@keyframes animate-svg-fill-4 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+.svg-elem-4 {
+ -webkit-animation: animate-svg-stroke-4 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.03s both,
+ animate-svg-fill-4 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.8300000000000001s both;
+ animation: animate-svg-stroke-4 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.03s both,
+ animate-svg-fill-4 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.8300000000000001s both;
+}
+
+@-webkit-keyframes animate-svg-stroke-5 {
+ 0% {
+ stroke-dashoffset: 1266.6910400390625px;
+ stroke-dasharray: 1266.6910400390625px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 1266.6910400390625px;
+ }
+}
+
+@keyframes animate-svg-stroke-5 {
+ 0% {
+ stroke-dashoffset: 1266.6910400390625px;
+ stroke-dasharray: 1266.6910400390625px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 1266.6910400390625px;
+ }
+}
+
+@-webkit-keyframes animate-svg-fill-5 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+@keyframes animate-svg-fill-5 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+.svg-elem-5 {
+ -webkit-animation: animate-svg-stroke-5 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.04s both,
+ animate-svg-fill-5 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.8400000000000001s both;
+ animation: animate-svg-stroke-5 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.04s both,
+ animate-svg-fill-5 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.8400000000000001s both;
+}
+
+@-webkit-keyframes animate-svg-stroke-6 {
+ 0% {
+ stroke-dashoffset: 132.3062286376953px;
+ stroke-dasharray: 132.3062286376953px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 132.3062286376953px;
+ }
+}
+
+@keyframes animate-svg-stroke-6 {
+ 0% {
+ stroke-dashoffset: 132.3062286376953px;
+ stroke-dasharray: 132.3062286376953px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 132.3062286376953px;
+ }
+}
+
+@-webkit-keyframes animate-svg-fill-6 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+@keyframes animate-svg-fill-6 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+.svg-elem-6 {
+ -webkit-animation: animate-svg-stroke-6 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.05s both,
+ animate-svg-fill-6 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.8500000000000001s both;
+ animation: animate-svg-stroke-6 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.05s both,
+ animate-svg-fill-6 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.8500000000000001s both;
+}
+
+@-webkit-keyframes animate-svg-stroke-7 {
+ 0% {
+ stroke-dashoffset: 177.990478515625px;
+ stroke-dasharray: 177.990478515625px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 177.990478515625px;
+ }
+}
+
+@keyframes animate-svg-stroke-7 {
+ 0% {
+ stroke-dashoffset: 177.990478515625px;
+ stroke-dasharray: 177.990478515625px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 177.990478515625px;
+ }
+}
+
+@-webkit-keyframes animate-svg-fill-7 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+@keyframes animate-svg-fill-7 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+.svg-elem-7 {
+ -webkit-animation: animate-svg-stroke-7 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.06s both,
+ animate-svg-fill-7 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.8600000000000001s both;
+ animation: animate-svg-stroke-7 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.06s both,
+ animate-svg-fill-7 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.8600000000000001s both;
+}
+
+@-webkit-keyframes animate-svg-stroke-8 {
+ 0% {
+ stroke-dashoffset: 278.4589538574219px;
+ stroke-dasharray: 278.4589538574219px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 278.4589538574219px;
+ }
+}
+
+@keyframes animate-svg-stroke-8 {
+ 0% {
+ stroke-dashoffset: 278.4589538574219px;
+ stroke-dasharray: 278.4589538574219px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 278.4589538574219px;
+ }
+}
+
+@-webkit-keyframes animate-svg-fill-8 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+@keyframes animate-svg-fill-8 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+.svg-elem-8 {
+ -webkit-animation: animate-svg-stroke-8 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.07s both,
+ animate-svg-fill-8 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.8700000000000001s both;
+ animation: animate-svg-stroke-8 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.07s both,
+ animate-svg-fill-8 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.8700000000000001s both;
+}
+
+@-webkit-keyframes animate-svg-stroke-9 {
+ 0% {
+ stroke-dashoffset: 239.96914672851562px;
+ stroke-dasharray: 239.96914672851562px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 239.96914672851562px;
+ }
+}
+
+@keyframes animate-svg-stroke-9 {
+ 0% {
+ stroke-dashoffset: 239.96914672851562px;
+ stroke-dasharray: 239.96914672851562px;
+ }
+
+ 100% {
+ stroke-dashoffset: 0;
+ stroke-dasharray: 239.96914672851562px;
+ }
+}
+
+@-webkit-keyframes animate-svg-fill-9 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+@keyframes animate-svg-fill-9 {
+ 0% {
+ fill: transparent;
+ }
+
+ 100% {
+ fill: var(--accent-11);
+ }
+}
+
+.svg-elem-9 {
+ -webkit-animation: animate-svg-stroke-9 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.08s both,
+ animate-svg-fill-9 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.88s both;
+ animation: animate-svg-stroke-9 1s cubic-bezier(0.47, 0, 0.745, 0.715) 0.08s both,
+ animate-svg-fill-9 0.7s cubic-bezier(0.47, 0, 0.745, 0.715) 0.88s both;
+}
diff --git a/front/src/components/NavBar/index.tsx b/front/src/components/NavBar/index.tsx
index 74d427e..7e96391 100644
--- a/front/src/components/NavBar/index.tsx
+++ b/front/src/components/NavBar/index.tsx
@@ -11,21 +11,32 @@ export default function NavBar() {
const { open } = useModal();
return (
-
+
diff --git a/front/src/components/OnBoarding/index.tsx b/front/src/components/OnBoarding/index.tsx
index 33f4d1f..2efc5e9 100644
--- a/front/src/components/OnBoarding/index.tsx
+++ b/front/src/components/OnBoarding/index.tsx
@@ -23,18 +23,11 @@ export default function OnBoarding() {
window.open("https://github.com/passkeys-4337/smart-wallet", "_blank")}
variant="soft"
+ size={"3"}
>
-
- Build for
-
-
+
diff --git a/front/src/components/SettingsPage/index.tsx b/front/src/components/SettingsPage/index.tsx
index aac138e..d02fa26 100644
--- a/front/src/components/SettingsPage/index.tsx
+++ b/front/src/components/SettingsPage/index.tsx
@@ -27,7 +27,7 @@ export default function SettingsPage() {
-
+
diff --git a/front/src/components/ThemeButton/index.tsx b/front/src/components/ThemeButton/index.tsx
index 99c9872..5135335 100644
--- a/front/src/components/ThemeButton/index.tsx
+++ b/front/src/components/ThemeButton/index.tsx
@@ -22,6 +22,7 @@ export default function ThemeButton({ style }: Props) {
{
if (theme === "system") {
setTheme(systemTheme === "dark" ? "light" : "dark");
diff --git a/front/src/components/TopBar/index.tsx b/front/src/components/TopBar/index.tsx
index 729bef9..2717a61 100644
--- a/front/src/components/TopBar/index.tsx
+++ b/front/src/components/TopBar/index.tsx
@@ -8,7 +8,7 @@ export default function TopBar() {
-
+
diff --git a/front/src/providers/TransactionProvider/index.tsx b/front/src/providers/TransactionProvider/index.tsx
deleted file mode 100644
index abb3b10..0000000
--- a/front/src/providers/TransactionProvider/index.tsx
+++ /dev/null
@@ -1,126 +0,0 @@
-"use client";
-
-import { PUBLIC_CLIENT, ENTRYPOINT_ADDRESS } from "@/constants";
-import { Me, useMe } from "@/providers/MeProvider";
-import { createContext, useCallback, useContext, useEffect, useState } from "react";
-import { Hex, Log } from "viem";
-
-const useTxHook = () => {
- const [txs, setTxs] = useState | null>(null);
- const [loading, setLoading] = useState(false);
-
- const { me } = useMe();
-
- const getLastTxs = useCallback(async (keyId: Hex) => {
- setLoading(true);
- const res = await fetch(`/api/users/${keyId}/txs`);
- const resJson = await res.json();
- setTxs((prev) => {
- const logs = resJson.logs.sort((a: Log, b: Log) => {
- return Number(b.blockNumber) - Number(a.blockNumber);
- });
- if (!prev) return logs;
- return [...prev, ...logs];
- });
- setLoading(false);
- }, []);
-
- const unwatchLogs = PUBLIC_CLIENT.watchContractEvent({
- address: ENTRYPOINT_ADDRESS,
- abi: [
- {
- inputs: [
- {
- internalType: "bytes32",
- name: "userOpHash",
- type: "bytes32",
- indexed: true,
- },
- {
- internalType: "address",
- name: "sender",
- type: "address",
- indexed: true,
- },
- {
- internalType: "address",
- name: "paymaster",
- type: "address",
- indexed: true,
- },
- {
- internalType: "uint256",
- name: "nonce",
- type: "uint256",
- indexed: false,
- },
- {
- internalType: "bool",
- name: "success",
- type: "bool",
- indexed: false,
- },
- {
- internalType: "uint256",
- name: "actualGasCost",
- type: "uint256",
- indexed: false,
- },
- {
- internalType: "uint256",
- name: "actualGasUsed",
- type: "uint256",
- indexed: false,
- },
- ],
- type: "event",
- name: "UserOperationEvent",
- anonymous: false,
- },
- ],
- eventName: "UserOperationEvent",
- args: { sender: me?.account },
- onLogs: (logs) => {
- setLoading(true);
- setTxs((prev) => {
- if (!prev) return logs;
- return [
- ...prev,
- ...logs.sort((a: Log, b: Log) => {
- return Number(b.blockNumber) - Number(a.blockNumber);
- }),
- ];
- });
- setLoading(false);
- },
- });
-
- useEffect(() => {
- if (!me) return;
- getLastTxs(me?.keyId);
- }, [me, getLastTxs]);
-
- return {
- loading,
- txs,
- getLastTxs,
- unwatchLogs,
- };
-};
-
-type UseTxHook = ReturnType;
-const TransactionContext = createContext(null);
-
-export const useTransaction = (): UseTxHook => {
- const context = useContext(TransactionContext);
- if (!context) {
- throw new Error("useTxHook must be used within a TransactionProvider");
- }
- return context;
-};
-
-export function TransactionProvider({ children }: { children: React.ReactNode }) {
- const hook = useTxHook();
-
- return {children};
-}