forked from Cookie-Jar-DAO/cookie-jar-v3
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseTokenRecoveryActions.ts
More file actions
147 lines (131 loc) · 3.33 KB
/
useTokenRecoveryActions.ts
File metadata and controls
147 lines (131 loc) · 3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
"use client";
import { useQueryClient } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import { isAddress } from "viem";
import {
useAccount,
useWaitForTransactionReceipt,
useWriteContract,
} from "wagmi";
import { cookieJarAbi } from "@/generated";
import { useToast } from "../app/useToast";
/**
* Pending token data structure
*/
export interface PendingToken {
tokenAddress: string;
tokenName: string;
tokenSymbol: string;
balance: bigint;
decimals: number;
isSwappable: boolean;
estimatedOutput?: bigint;
}
/**
* Hook for managing token recovery actions (admin only)
*/
export const useTokenRecoveryActions = (jarAddress: `0x${string}`) => {
const { address: _address } = useAccount();
const { toast } = useToast();
const queryClient = useQueryClient();
// Transaction states
const [isSwapping, setIsSwapping] = useState(false);
const [swappingTokenAddress, setSwappingTokenAddress] = useState<
string | null
>(null);
// Write contract hooks
const {
writeContract: swapTokensWrite,
data: swapHash,
isPending: swapPending,
} = useWriteContract();
// Transaction receipt
const {
isLoading: swapLoading,
isSuccess: swapSuccess,
error: swapError,
} = useWaitForTransactionReceipt({
hash: swapHash,
});
// Handle success and error states
useEffect(() => {
if (swapSuccess) {
toast({
title: "Swap Successful",
description: `Token has been swapped successfully.`,
});
setIsSwapping(false);
setSwappingTokenAddress(null);
// Invalidate relevant queries
queryClient.invalidateQueries({
queryKey: ["pendingTokens", jarAddress],
});
queryClient.invalidateQueries({ queryKey: ["jarBalance", jarAddress] });
}
}, [swapSuccess, toast, queryClient, jarAddress]);
useEffect(() => {
if (swapError) {
toast({
title: "Swap Failed",
description: swapError.message || "Failed to swap token.",
variant: "destructive",
});
setIsSwapping(false);
setSwappingTokenAddress(null);
}
}, [swapError, toast]);
/**
* Swap pending tokens to the jar's token
*/
const swapPendingToken = async (tokenAddress: string) => {
if (!isAddress(tokenAddress)) {
toast({
title: "Invalid Token",
description: "Invalid token address provided.",
variant: "destructive",
});
return;
}
try {
setIsSwapping(true);
setSwappingTokenAddress(tokenAddress);
await swapTokensWrite({
address: jarAddress,
abi: cookieJarAbi,
functionName: "swapPendingTokens",
args: [
tokenAddress as `0x${string}`,
BigInt(0), // amount - 0 means swap all pending balance
BigInt(0), // minJarTokensOut - 0 means no minimum (should be calculated from oracle in production)
],
});
} catch (error: any) {
toast({
title: "Swap Failed",
description: error.message || "Failed to initiate token swap.",
variant: "destructive",
});
setIsSwapping(false);
setSwappingTokenAddress(null);
}
};
/**
* Check if currently swapping a specific token
*/
const isSwappingToken = (tokenAddress: string): boolean => {
return (
swappingTokenAddress === tokenAddress &&
(swapPending || swapLoading || isSwapping)
);
};
return {
// Actions
swapPendingToken,
// Loading states
isSwapping: swapPending || swapLoading || isSwapping,
swappingTokenAddress,
isSwappingToken,
// Transaction hash
swapHash,
};
};