Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace effects with react query callbacks #314

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 37 additions & 47 deletions apps/bob-pay/src/app/[lang]/send/Send.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useLingui } from '@lingui/react';
import { mergeProps } from '@react-aria/utils';
import { useMutation } from '@tanstack/react-query';
import Big from 'big.js';
import { useEffect, useMemo, useState } from 'react';
import { useMemo, useState } from 'react';
import { Address, encodeFunctionData, erc20Abi, isAddress, maxInt256 } from 'viem';
import { useAccount, useSendTransaction, useWaitForTransactionReceipt, useWriteContract } from 'wagmi';

Expand Down Expand Up @@ -72,7 +72,15 @@ const Send = ({ ticker: tickerProp = 'WBTC', recipient }: SendProps): JSX.Elemen
const [isGroupAmount, setGroupAmount] = useState(false);

const { getPrice } = usePrices();
const { getBalance, isPending } = useBalances(CHAIN);
const { getBalance } = useBalances(CHAIN, {
meta: {
onSettled: () => {
if (form.values[TRANSFER_TOKEN_AMOUNT]) {
form.validateField(TRANSFER_TOKEN_AMOUNT);
}
}
}
});

const { data: tokens } = useTokens(CHAIN);

Expand Down Expand Up @@ -143,8 +151,7 @@ const Send = ({ ticker: tickerProp = 'WBTC', recipient }: SendProps): JSX.Elemen
const {
data: eoaTransferTx,
mutate: eoaTransfer,
isPending: isEOATransferPending,
error: eoaTransferError
isPending: isEOATransferPending
} = useMutation({
mutationKey: ['eoa-transfer', amount, form.values[TRANSFER_TOKEN_RECIPIENT]],
mutationFn: async ({
Expand Down Expand Up @@ -190,39 +197,33 @@ const Send = ({ ticker: tickerProp = 'WBTC', recipient }: SendProps): JSX.Elemen
});

return txid;
},
onError(error) {
toast.error(error.message);
// eslint-disable-next-line no-console
console.log(error);
}
});

const { isLoading: isWaitingEoaTransferTxConfirmation, data: eoaTransferTransactionReceipt } =
useWaitForTransactionReceipt({
hash: eoaTransferTx
});

useEffect(() => {
if (eoaTransferTransactionReceipt?.status === 'success') {
toast.success(t(i18n)`Successfully sent ${amount} ${token?.currency.symbol}`);

form.resetForm();
setAmount('');
setGroupAmount(false);
setTicker(tickerProp);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [eoaTransferTransactionReceipt]);
const { isLoading: isWaitingEoaTransferTxConfirmation } = useWaitForTransactionReceipt({
hash: eoaTransferTx,
query: {
meta: {
onSuccess: (data) => {
if ((data as { status: 'success' } | undefined)?.status === 'success') {
toast.success(t(i18n)`Successfully sent ${amount} ${token?.currency.symbol}`);

useEffect(() => {
if (eoaTransferError) {
toast.error(eoaTransferError.message);
// eslint-disable-next-line no-console
console.log(eoaTransferError);
form.resetForm();
setAmount('');
setGroupAmount(false);
setTicker(tickerProp);
}
}
}
}
}, [eoaTransferError]);
});

const {
mutate: smartAccountTransfer,
isPending: isSmartAccountTransferPending,
error: smartAccountTransferError
} = useMutation({
const { mutate: smartAccountTransfer, isPending: isSmartAccountTransferPending } = useMutation({
mutationKey: ['smart-account-transfer', amount, form.values[TRANSFER_TOKEN_RECIPIENT]],
onSuccess: (tx, variables) => {
if (!tx) {
Expand All @@ -240,6 +241,11 @@ const Send = ({ ticker: tickerProp = 'WBTC', recipient }: SendProps): JSX.Elemen
setGroupAmount(false);
setTicker(tickerProp);
},
onError(error) {
toast.error(t(i18n)`Failed to submit transaction`);
// eslint-disable-next-line no-console
console.log(error);
},
mutationFn: async ({
recipient,
currencyAmount
Expand Down Expand Up @@ -323,22 +329,6 @@ const Send = ({ ticker: tickerProp = 'WBTC', recipient }: SendProps): JSX.Elemen
}
});

useEffect(() => {
if (smartAccountTransferError) {
toast.error(t(i18n)`Failed to submit transaction`);
// eslint-disable-next-line no-console
console.log(smartAccountTransferError);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [smartAccountTransferError]);

useEffect(() => {
if (!isPending && form.values[TRANSFER_TOKEN_AMOUNT]) {
form.validateField(TRANSFER_TOKEN_AMOUNT);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isPending]);

const tokenInputItems = useMemo(
() =>
tokens?.map((token) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { Currency, CurrencyAmount } from '@gobob/currency';
import { usePrices } from '@gobob/hooks';
import { Flex, Span, useCurrencyFormatter, useLocale } from '@gobob/ui';
import { Item } from '@react-stately/collections';
import { useMemo, useState } from 'react';
import Big from 'big.js';
import { useEffect, useMemo, useState } from 'react';

import { ButtonGroup } from '../ButtonGroup';

Expand All @@ -25,12 +25,15 @@ const TokenButtonGroup = ({ isSelected, currency, balance, onSelectionChange }:
const { getPrice, data: pricesData } = usePrices();

const [key, setKey] = useState<string>();
const [prevIsSelected, setPrevIsSelected] = useState(false);

if (prevIsSelected !== isSelected) {
setPrevIsSelected(isSelected);

useEffect(() => {
if (!isSelected) {
setKey(undefined);
}
}, [isSelected]);
}

const amounts = useMemo(() => {
if (currency.symbol === 'WBTC') {
Expand Down
5 changes: 3 additions & 2 deletions apps/bob-pay/src/hooks/useBalances.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ChainId } from '@gobob/chains';
import { CurrencyAmount, ERC20Token, Ether } from '@gobob/currency';
import { useQuery } from '@tanstack/react-query';
import { useQuery, DefinedInitialDataOptions } from '@tanstack/react-query';
import { useCallback, useMemo } from 'react';
import { Address, erc20Abi } from 'viem';
import { usePublicClient } from 'wagmi';
Expand All @@ -12,7 +12,7 @@ import { INTERVAL } from '@/constants';

type Balances = Record<Address, CurrencyAmount<ERC20Token | Ether>>;

const useBalances = (chainId: ChainId) => {
const useBalances = (chainId: ChainId, query?: Pick<DefinedInitialDataOptions, 'meta'>) => {
const publicClient = usePublicClient({ chainId });
const address = useDynamicAddress();

Expand All @@ -22,6 +22,7 @@ const useBalances = (chainId: ChainId) => {
const native = useMemo(() => tokens.find((token) => token.currency.isNative), [tokens]);

const { data: balances, ...queryResult } = useQuery({
...query,
queryKey: ['balances', chainId, address],
enabled: Boolean(address && publicClient && tokens),
queryFn: async () => {
Expand Down
21 changes: 21 additions & 0 deletions apps/bob-pay/src/lib/react-query/react-query.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import '@tanstack/react-query';
import { DefaultError, Query } from '@tanstack/react-query';

// https://tanstack.com/query/latest/docs/framework/react/typescript#typing-meta
interface CustomQueryMeta<TQueryFnData = unknown> extends Record<string, unknown> {
onSuccess?: ((data: TQueryFnData, query: Query<TQueryFnData, unknown, unknown>) => void) | undefined;
onError?: ((error: DefaultError, query: Query<TQueryFnData, unknown, unknown>) => void) | undefined;
onSettled?:
| ((
data: TQueryFnData | undefined,
error: DefaultError | null,
query: Query<TQueryFnData, unknown, unknown>
) => void)
| undefined;
}

declare module '@tanstack/react-query' {
interface Register extends Record<string, unknown> {
queryMeta: CustomQueryMeta;
}
}
25 changes: 15 additions & 10 deletions apps/evm/src/app/[lang]/(bridge)/hooks/useGateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { BITCOIN } from '@gobob/tokens';
import { toast } from '@gobob/ui';
import { t } from '@lingui/macro';
import { useLingui } from '@lingui/react';
import { Dispatch, SetStateAction, useCallback, useMemo, useState } from 'react';
import * as Sentry from '@sentry/nextjs';
import {
Optional,
Expand All @@ -23,7 +24,6 @@ import {
useQueryClient,
UseQueryResult
} from '@tanstack/react-query';
import { Dispatch, SetStateAction, useCallback, useEffect, useMemo, useState } from 'react';
import { DebouncedState, useDebounceValue } from 'usehooks-ts';
import { Address, isAddress } from 'viem';
import { useAccount } from 'wagmi';
Expand Down Expand Up @@ -218,9 +218,16 @@ const useGateway = ({
}
});

const estimateFeeErrorMessage = t(i18n)`Failed to get estimated fee`;

const feeRatesQueryResult = useSatsFeeRate({
query: {
select: feeRatesSelect
select: feeRatesSelect,
meta: {
onError() {
toast.error(estimateFeeErrorMessage);
}
}
}
});

Expand All @@ -234,17 +241,15 @@ const useGateway = ({
feeRate: feeRate,
query: {
enabled: feeEstimateQueryEnabled,
select: (data) => CurrencyAmount.fromRawAmount(BITCOIN, data.amount)
select: (data) => CurrencyAmount.fromRawAmount(BITCOIN, data.amount),
meta: {
onError() {
toast.error(estimateFeeErrorMessage);
}
}
}
});

useEffect(() => {
if (feeEstimateQueryResult.error || feeRatesQueryResult.error) {
toast.error(t(i18n)`Failed to get estimated fee`);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [feeRatesQueryResult.error, feeEstimateQueryResult.error]);

const balance = useMemo(
() => getBalanceAmount(satsBalance?.total, feeEstimateQueryResult.data, liquidityQueryResult.data?.liquidityAmount),
[liquidityQueryResult.data?.liquidityAmount, satsBalance?.total, feeEstimateQueryResult.data]
Expand Down
7 changes: 0 additions & 7 deletions apps/evm/src/app/[lang]/(bridge)/hooks/useGatewayForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,6 @@ const useGatewayForm = ({ query, defaultAsset, onSubmit }: UseGatewayFormProps)

const { address: btcAddress } = useSatsAccount();

useEffect(() => {
if (!query.fee.estimate.data || !form.values[BRIDGE_AMOUNT]) return;

form.validateField(BRIDGE_AMOUNT);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [query.fee.rates.data]);

const params: BridgeFormValidationParams = {
[BRIDGE_AMOUNT]: {
minAmount: new Big(query.minAmount.toExact()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { ChainId } from '@gobob/chains';
import { ERC20Token, Token } from '@gobob/currency';
import { useCallback, useMemo } from 'react';

import { useGetStrategies } from '@/hooks';
import { useStrategiesContractData } from './useStrategiesContractData';

import { useGetStrategies } from '@/hooks';

type StrategyData = {
tvl?: number | null;
raw: GatewayStrategyContract;
Expand Down Expand Up @@ -48,7 +49,7 @@ const useGetStakingStrategies = () => {
userStaked
};
}),
[strategiesContractData]
[strategies, strategiesContractData]
);

return { data: strategiesData };
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useState } from 'react';
import { useCallback, useState } from 'react';
import OtpInput, { OTPInputProps } from 'react-otp-input';
import { useLabel } from '@react-aria/label';
import { Flex, Label, P } from '@gobob/ui';
Expand All @@ -25,6 +25,7 @@ const ReferralInput = ({ onChange, errorMessage, ...props }: ReferralInputProps)
const { i18n } = useLingui();

const [otp, setOtp] = useState(refCode || '');
const [prevOtp, setPrevOtp] = useState(otp);
const labelText = t(i18n)`Enter your access code (optional):`;

const { fieldProps, labelProps } = useLabel({ label: labelText });
Expand All @@ -37,12 +38,11 @@ const ReferralInput = ({ onChange, errorMessage, ...props }: ReferralInputProps)
[onChange]
);

useEffect(() => {
if (!otp) return;
if (prevOtp !== otp) {
setPrevOtp(otp);

handleChange(otp);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [otp]);
if (otp) handleChange(otp);
}

const hasError = !!errorMessage;

Expand Down
21 changes: 21 additions & 0 deletions apps/evm/src/lib/react-query/react-query.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import '@tanstack/react-query';
import { DefaultError, Query } from '@tanstack/react-query';

// https://tanstack.com/query/latest/docs/framework/react/typescript#typing-meta
interface CustomQueryMeta<TQueryFnData = unknown> extends Record<string, unknown> {
onSuccess?: ((data: TQueryFnData, query: Query<TQueryFnData, unknown, unknown>) => void) | undefined;
onError?: ((error: DefaultError, query: Query<TQueryFnData, unknown, unknown>) => void) | undefined;
onSettled?:
| ((
data: TQueryFnData | undefined,
error: DefaultError | null,
query: Query<TQueryFnData, unknown, unknown>
) => void)
| undefined;
}

declare module '@tanstack/react-query' {
interface Register extends Record<string, unknown> {
queryMeta: CustomQueryMeta;
}
}
4 changes: 2 additions & 2 deletions apps/evm/src/locales/en.po
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ msgstr "Enter destination address"
msgid "Enter referral code (optional)"
msgstr "Enter referral code (optional)"

#: src/app/[lang]/sign-up/components/ReferralInput/ReferralInput.tsx:28
#: src/app/[lang]/sign-up/components/ReferralInput/ReferralInput.tsx:29
msgid "Enter your access code (optional):"
msgstr "Enter your access code (optional):"

Expand Down Expand Up @@ -660,7 +660,7 @@ msgstr "Failed to connect to {0}"
#~ msgid "Failed to finalize."
#~ msgstr "Failed to finalize."

#: src/app/[lang]/(bridge)/hooks/useGateway.ts:243
#: src/app/[lang]/(bridge)/hooks/useGateway.ts:221
msgid "Failed to get estimated fee"
msgstr "Failed to get estimated fee"

Expand Down
4 changes: 2 additions & 2 deletions apps/evm/src/locales/zh.po
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ msgstr ""
msgid "Enter referral code (optional)"
msgstr ""

#: src/app/[lang]/sign-up/components/ReferralInput/ReferralInput.tsx:28
#: src/app/[lang]/sign-up/components/ReferralInput/ReferralInput.tsx:29
msgid "Enter your access code (optional):"
msgstr ""

Expand Down Expand Up @@ -660,7 +660,7 @@ msgstr ""
#~ msgid "Failed to finalize."
#~ msgstr ""

#: src/app/[lang]/(bridge)/hooks/useGateway.ts:243
#: src/app/[lang]/(bridge)/hooks/useGateway.ts:221
msgid "Failed to get estimated fee"
msgstr ""

Expand Down
Loading
Loading