Hey is a decentralized and permissionless social media app built with Lens Protocol 馃尶
1import { ERRORS } from "@hey/data/errors";
2import getTransactionData from "@hey/helpers/getTransactionData";
3import type {
4 SelfFundedTransactionRequestFragment,
5 SponsoredTransactionRequestFragment,
6 TransactionWillFailFragment
7} from "@hey/indexer";
8import type { ApolloClientError } from "@hey/types/errors";
9import { sendEip712Transaction, sendTransaction } from "viem/zksync";
10import { useWalletClient } from "wagmi";
11import useHandleWrongNetwork from "./useHandleWrongNetwork";
12
13type AnyTransactionRequestFragment =
14 | SelfFundedTransactionRequestFragment
15 | SponsoredTransactionRequestFragment
16 | TransactionWillFailFragment
17 | { __typename?: string; hash?: unknown }
18 | ((...args: never[]) => unknown);
19
20const useTransactionLifecycle = () => {
21 const { data } = useWalletClient();
22 const handleWrongNetwork = useHandleWrongNetwork();
23
24 const handleSponsoredTransaction = async (
25 transactionData: AnyTransactionRequestFragment,
26 onCompleted: (hash: string) => void
27 ) => {
28 if (
29 typeof transactionData === "function" ||
30 transactionData.__typename !== "SponsoredTransactionRequest" ||
31 !("raw" in transactionData)
32 ) {
33 return;
34 }
35 await handleWrongNetwork();
36 if (!data) return;
37 return onCompleted(
38 await sendEip712Transaction(data, {
39 account: data.account,
40 ...getTransactionData(transactionData.raw, { sponsored: true })
41 })
42 );
43 };
44
45 const handleSelfFundedTransaction = async (
46 transactionData: AnyTransactionRequestFragment,
47 onCompleted: (hash: string) => void
48 ) => {
49 if (
50 typeof transactionData === "function" ||
51 transactionData.__typename !== "SelfFundedTransactionRequest" ||
52 !("raw" in transactionData)
53 ) {
54 return;
55 }
56 await handleWrongNetwork();
57 if (!data) return;
58 return onCompleted(
59 await sendTransaction(data, {
60 account: data.account,
61 ...getTransactionData(transactionData.raw)
62 })
63 );
64 };
65
66 const handleTransactionLifecycle = async ({
67 transactionData,
68 onCompleted,
69 onError
70 }: {
71 transactionData: AnyTransactionRequestFragment;
72 onCompleted: (hash: string) => void;
73 onError: (error: ApolloClientError) => void;
74 }) => {
75 try {
76 if (typeof transactionData === "function") {
77 return onError({ message: ERRORS.SomethingWentWrong });
78 }
79 switch (transactionData.__typename) {
80 case "SponsoredTransactionRequest":
81 return await handleSponsoredTransaction(transactionData, onCompleted);
82 case "SelfFundedTransactionRequest":
83 return await handleSelfFundedTransaction(
84 transactionData,
85 onCompleted
86 );
87 case "TransactionWillFail":
88 if ("reason" in transactionData) {
89 return onError({ message: transactionData.reason });
90 }
91 return onError({ message: ERRORS.SomethingWentWrong });
92 default:
93 onError({ message: ERRORS.SomethingWentWrong });
94 return;
95 }
96 } catch (error) {
97 return onError(error);
98 }
99 };
100
101 return handleTransactionLifecycle;
102};
103
104export default useTransactionLifecycle;