import { useCallback, useMemo } from 'react';
import { useAccount, useChainId } from 'wagmi';
import { getChainExplorer } from '../../core/network/getChainExplorer';
import { Spinner } from '../../internal/components/Spinner';
import { cn, pressable, text } from '../../styles/theme';
import type { TransactionButtonProps } from '../types';
import { useTransactionContext } from './TransactionProvider';
export function TransactionButton({
className,
disabled = false,
text: idleText = 'Transact',
render,
}: TransactionButtonProps) {
const context = useTransactionContext();
const {
chainId,
errorMessage,
isLoading,
onSubmit,
receipt,
transactions,
transactionHash,
transactionId,
} = context;
const { address } = useAccount();
// eslint-disable-next-line react-hooks/rules-of-hooks
const accountChainId = chainId ?? useChainId();
const isMissingProps = !transactions || !address;
const isWaitingForReceipt = !!transactionId || !!transactionHash;
const isDisabled =
!receipt &&
(isLoading || isMissingProps || isWaitingForReceipt || disabled);
const handleSuccess = useCallback(() => {
// SW will have txn id so open in wallet
if (receipt && transactionId && transactionHash && chainId && address) {
const url = new URL('https://wallet.coinbase.com/assets/transactions');
url.searchParams.set('contentParams[txHash]', transactionHash);
url.searchParams.set('contentParams[chainId]', JSON.stringify(chainId));
url.searchParams.set('contentParams[fromAddress]', address);
return window.open(url, '_blank', 'noopener,noreferrer');
}
// EOA will not have txn id so open in explorer
const chainExplorer = getChainExplorer(accountChainId);
return window.open(
`${chainExplorer}/tx/${transactionHash}`,
'_blank',
'noopener,noreferrer',
);
}, [
address,
chainId,
receipt,
transactionId,
transactionHash,
accountChainId,
]);
const buttonContent = useMemo(() => {
// txn successful
if (receipt) {
return 'View transaction';
}
if (errorMessage) {
return 'Try again';
}
if (isLoading) {
return ;
}
return idleText;
}, [isLoading, errorMessage, receipt, idleText]);
const handleSubmit = useCallback(() => {
if (receipt) {
handleSuccess();
} else {
onSubmit();
}
}, [onSubmit, receipt, handleSuccess]);
const status = useMemo(() => {
if (receipt) {
return 'success';
}
if (errorMessage) {
return 'error';
}
if (isLoading) {
return 'pending';
}
return 'default';
}, [isLoading, errorMessage, receipt]);
if (render) {
return render({
status,
context,
onSubmit: handleSubmit,
onSuccess: handleSuccess,
isDisabled,
});
}
return (
);
}