Skip to content

Commit 5a448ae

Browse files
committed
feat: claim fee flow
1 parent 3c8a093 commit 5a448ae

2 files changed

Lines changed: 52 additions & 105 deletions

File tree

features/claim/claim-form/claim-form-context/claim-form-provider.tsx

Lines changed: 21 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@ import {
55
useCallback,
66
createContext,
77
useContext,
8-
useState,
98
} from 'react';
109
import { isAddress, ReadContractErrorType } from 'viem';
1110
import { useReadContract } from 'wagmi';
1211
import { FormProvider, useForm } from 'react-hook-form';
1312

14-
import { useFormControllerRetry } from 'shared/hook-form/form-controller/use-form-controller-retry-delegate';
1513
import { useClaim } from 'features/claim/claim-form/hooks';
1614
import { useVaultInfo } from 'modules/vaults';
1715

@@ -24,11 +22,6 @@ import {
2422
import { dashboardAbi } from 'abi/dashboard-abi';
2523
import { ClaimFormSchema } from 'features/claim/claim-form/types';
2624
import invariant from 'tiny-invariant';
27-
import {
28-
SubmitPayload,
29-
SubmitStepEnum,
30-
} from 'shared/components/submit-modal/types';
31-
import { SubmitModal } from 'shared/components';
3225

3326
type ClaimDataContextValue = {
3427
availableToClaim: bigint | undefined;
@@ -53,11 +46,28 @@ export const useClaimFormData = () => {
5346
export const ClaimFormProvider: FC<{ children: ReactNode }> = ({
5447
children,
5548
}) => {
56-
const [submitStep, setSubmitStep] = useState<SubmitPayload>(() => ({
57-
step: SubmitStepEnum.edit,
58-
}));
5949
const { activeVault } = useVaultInfo();
6050

51+
const formObject = useForm<ClaimFormSchema>({
52+
defaultValues: {
53+
recipient: '',
54+
},
55+
mode: 'all',
56+
// TODO: validation
57+
reValidateMode: 'onChange',
58+
});
59+
const { claim, retryEvent } = useClaim();
60+
61+
const onSubmit = useCallback(
62+
async ({ recipient }: ClaimFormSchema) => {
63+
// TODO: add validation, remove stub
64+
if (!isAddress(recipient)) return false;
65+
66+
return claim(recipient);
67+
},
68+
[claim],
69+
);
70+
6171
const {
6272
data: availableToClaim,
6373
isFetching: isLoadingClaimInfo,
@@ -82,63 +92,21 @@ export const ClaimFormProvider: FC<{ children: ReactNode }> = ({
8292
[availableToClaim, isLoadingClaimInfo, isErrorClaimInfo, errorClaimInfo],
8393
);
8494

85-
const formObject = useForm<ClaimFormSchema>({
86-
defaultValues: {
87-
recipient: '',
88-
},
89-
mode: 'all',
90-
reValidateMode: 'onChange',
91-
});
92-
const { callClaim } = useClaim();
93-
94-
const { retryEvent, retryFire } = useFormControllerRetry();
95-
const setModalState = useCallback((submitStep: SubmitPayload) => {
96-
setSubmitStep(submitStep);
97-
}, []);
98-
99-
const onSubmit = useCallback(
100-
async ({ recipient }: ClaimFormSchema) => {
101-
if (recipient && isAddress(recipient)) {
102-
try {
103-
setModalState({ step: SubmitStepEnum.initiate });
104-
const tx = await callClaim(recipient, setModalState);
105-
setModalState({ step: SubmitStepEnum.overview, tx });
106-
return true;
107-
} catch (err) {
108-
if (
109-
err instanceof Error &&
110-
err.message.includes('User rejected the request')
111-
) {
112-
setModalState({ step: SubmitStepEnum.reject });
113-
} else {
114-
setModalState({ step: SubmitStepEnum.error });
115-
}
116-
}
117-
}
118-
119-
return false;
120-
},
121-
// eslint-disable-next-line react-hooks/exhaustive-deps
122-
[callClaim],
123-
);
124-
12595
const formControllerValue: FormControllerContextValueType<ClaimFormSchema> =
12696
useMemo(
12797
() => ({
12898
onSubmit,
12999
retryEvent,
130-
retryFire,
131100
onReset: formObject.reset,
132101
}),
133-
[retryFire, retryEvent, onSubmit, formObject.reset],
102+
[retryEvent, onSubmit, formObject.reset],
134103
);
135104

136105
return (
137106
<ClaimDataContext.Provider value={claimInfo}>
138107
<FormProvider {...formObject}>
139108
<FormControllerContext.Provider value={formControllerValue}>
140109
<FormController>{children}</FormController>
141-
<SubmitModal submitStep={submitStep} setModalState={setModalState} />
142110
</FormControllerContext.Provider>
143111
</FormProvider>
144112
</ClaimDataContext.Provider>

features/claim/claim-form/hooks/use-claim.ts

Lines changed: 31 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,50 @@
11
import { useCallback } from 'react';
2-
import {
3-
useConfig,
4-
usePublicClient,
5-
useWriteContract,
6-
useEstimateGas,
7-
useAccount,
8-
} from 'wagmi';
2+
import { useEstimateGas, useAccount } from 'wagmi';
93
import { Address, encodeFunctionData } from 'viem';
104

115
import { dashboardAbi } from 'abi/dashboard-abi';
12-
import { useDappStatus } from 'modules/web3/hooks/use-dapp-status';
136
import { useVaultInfo } from 'modules/vaults';
147
import invariant from 'tiny-invariant';
15-
import {
16-
SubmitPayload,
17-
SubmitStepEnum,
18-
} from 'shared/components/submit-modal/types';
198
import { useVaultPermission } from 'modules/vaults/hooks/use-vault-permissions';
209
import { fallbackedAddress } from 'utils/fallbacked-address';
10+
import { useSendTransaction, withSuccess } from 'modules/web3';
2111

22-
export const useClaim = (onMutate = () => {}) => {
23-
const { chainId } = useDappStatus();
24-
const wagmiConfig = useConfig();
12+
export const useClaim = () => {
2513
const { activeVault } = useVaultInfo();
26-
const publicClient = usePublicClient();
2714
const owner = activeVault?.owner;
15+
const { sendTX, ...rest } = useSendTransaction();
2816

29-
const { data: claimTx, writeContractAsync } = useWriteContract({
30-
config: wagmiConfig,
31-
mutation: {
32-
onMutate,
33-
},
34-
});
17+
return {
18+
claim: useCallback(
19+
async (recipient: Address) => {
20+
invariant(owner, '[useClaim] owner is undefined');
3521

36-
const callClaim = useCallback(
37-
async (
38-
recipient: Address,
39-
setModalState: (submitStep: SubmitPayload) => void,
40-
) => {
41-
invariant(owner, '[useClaimDashboard] owner is not available');
42-
invariant(
43-
publicClient,
44-
'[useClaimDashboard] publicClient is not available',
45-
);
22+
const loadingActionText = `Claiming node operator fee`;
23+
const mainActionCompleteText = `Claimed node operator fee`;
4624

47-
setModalState({ step: SubmitStepEnum.confirming });
48-
const tx = await writeContractAsync({
49-
abi: dashboardAbi,
50-
address: owner,
51-
functionName: 'claimNodeOperatorFee',
52-
args: [recipient],
53-
chainId,
54-
});
25+
const claimCall = {
26+
to: owner,
27+
data: encodeFunctionData({
28+
abi: dashboardAbi,
29+
functionName: 'claimNodeOperatorFee',
30+
args: [recipient],
31+
}),
32+
loadingActionText,
33+
};
5534

56-
setModalState({ step: SubmitStepEnum.submitting, tx });
57-
await publicClient.waitForTransactionReceipt({
58-
hash: tx,
59-
});
35+
const { success } = await withSuccess(
36+
sendTX({
37+
transactions: [claimCall],
38+
mainActionLoadingText: loadingActionText,
39+
mainActionCompleteText,
40+
}),
41+
);
6042

61-
return tx;
62-
},
63-
[chainId, writeContractAsync, owner, publicClient],
64-
);
65-
66-
return {
67-
callClaim,
68-
claimTx,
43+
return success;
44+
},
45+
[owner, sendTX],
46+
),
47+
...rest,
6948
};
7049
};
7150

0 commit comments

Comments
 (0)