Skip to content

Commit

Permalink
Fix issues with Celo Terminal signing and disconnection
Browse files Browse the repository at this point in the history
  • Loading branch information
jmrossy committed Apr 27, 2024
1 parent 4e9c649 commit f1864ac
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/app/account/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { useAccount } from 'wagmi';
export default function Page() {
const account = useAccount();
const address = account?.address;
usePageInvariant(!!address, '/', 'No account connected');
usePageInvariant(!!address, '/');

const { balance: walletBalance } = useBalance(address);
const { lockedBalances } = useLockedStatus(address);
Expand Down
3 changes: 3 additions & 0 deletions src/config/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ export const EXECUTION_STAGE_EXPIRY_TIME = 259_200_000; // 3 days

// Delegation
export const MAX_NUM_DELEGATEES = 10;

// Wallets
export const WALLET_CONNECT_CONNECTOR_ID = 'walletConnect';
2 changes: 0 additions & 2 deletions src/config/wagmi.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { RainbowKitProvider, connectorsForWallets, lightTheme } from '@rainbow-me/rainbowkit';
import '@rainbow-me/rainbowkit/styles.css';
import {
ledgerWallet,
metaMaskWallet,
omniWallet,
rainbowWallet,
Expand Down Expand Up @@ -29,7 +28,6 @@ const connectors = connectorsForWallets(
rainbowWallet,
omniWallet,
trustWallet,
ledgerWallet,
],
},
],
Expand Down
2 changes: 1 addition & 1 deletion src/features/account/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export function useLockedBalance(address?: Address) {
};
}

// Note, this retrieves the address's info from the Accounts contract
// Note, this retrieves the address' info from the Accounts contract
// It has nothing to do with wallets or backend services
export function useAccountDetails(address?: Address) {
const {
Expand Down
7 changes: 5 additions & 2 deletions src/features/locking/useLockedStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { lockedGoldABI } from '@celo/abis';
import { useQuery } from '@tanstack/react-query';
import { useToastError } from 'src/components/notifications/useToastError';
import { Addresses } from 'src/config/contracts';
import { useAccountDetails } from 'src/features/account/hooks';
import { LockedStatus, PendingWithdrawal } from 'src/features/locking/types';
import { logger } from 'src/utils/logger';
import { PublicClient } from 'viem';
Expand All @@ -10,10 +11,12 @@ import { usePublicClient } from 'wagmi';
export function useLockedStatus(address?: Address) {
const publicClient = usePublicClient();

const { isRegistered } = useAccountDetails(address);

const { isLoading, isError, error, data, refetch } = useQuery({
queryKey: ['useLockedStatus', publicClient, address],
queryKey: ['useLockedStatus', publicClient, address, isRegistered],
queryFn: async () => {
if (!address || !publicClient) return null;
if (!address || !isRegistered || !publicClient) return null;
logger.debug('Fetching locked status balance and withdrawals');
return fetchLockedStatus(publicClient, address);
},
Expand Down
2 changes: 1 addition & 1 deletion src/features/staking/ActiveStakesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export function ActiveStakesTable({
return <FullWidthSpinner>Loading staking data</FullWidthSpinner>;
}

if (!objLength(groupToStake)) {
if (!tableData.length) {
return (
<HeaderAndSubheader
header="No active stakes"
Expand Down
52 changes: 48 additions & 4 deletions src/features/transactions/useWriteContractWithReceipt.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import { useEffect, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { useToastTxSuccess } from 'src/components/notifications/TxSuccessToast';
import { useToastError } from 'src/components/notifications/useToastError';
import { WALLET_CONNECT_CONNECTOR_ID } from 'src/config/consts';
import { logger } from 'src/utils/logger';
import { capitalizeFirstLetter } from 'src/utils/strings';
import { TransactionReceipt } from 'viem';
import { useWaitForTransactionReceipt, useWriteContract } from 'wagmi';
import { TransactionReceipt, encodeFunctionData } from 'viem';
import {
Config,
useAccount,
usePublicClient,
useWaitForTransactionReceipt,
useWriteContract,
} from 'wagmi';
import type { WriteContractMutate } from 'wagmi/query';

// Special case handling for this common error to provide a more specific error message
const CHAIN_MISMATCH_ERROR = 'does not match the target chain';
Expand All @@ -13,6 +22,9 @@ export function useWriteContractWithReceipt(
onSuccess?: (receipt: TransactionReceipt) => any,
showTxSuccessToast = false,
) {
const account = useAccount();
const publicClient = usePublicClient();

const {
data: hash,
error: writeError,
Expand All @@ -21,6 +33,38 @@ export function useWriteContractWithReceipt(
writeContract,
} = useWriteContract();

const writeContractWithTxPrep = useCallback(
async (args: Parameters<WriteContractMutate<Config, unknown>>[0]) => {
// Some WalletConnect-ed wallets like Celo Terminal require that the tx be fully populated
if (account?.connector?.id === WALLET_CONNECT_CONNECTOR_ID) {
if (!publicClient) {
logger.error('Public client not ready for WalletConnect wallet tx');
return;
}

logger.debug('Preparing transaction request for WalletConnect wallet');
const encodedData = encodeFunctionData(args);
const request = await publicClient.prepareTransactionRequest({
to: args.address,
chainId: args.chainId,
value: args.value,
data: encodedData,
account: account.address,
});
logger.debug('Transaction request prepared, triggering write');
writeContract({
...args,
gas: request.gas,
gasPrice: request.gasPrice,
} as any);
} else {
logger.debug('Trigger transaction write');
writeContract(args);
}
},
[writeContract, publicClient, account],
);

const {
isLoading: isConfirming,
isSuccess: isConfirmed,
Expand Down Expand Up @@ -68,6 +112,6 @@ export function useWriteContractWithReceipt(
isError: isWriteError || isWaitError,
isLoading: isPending || isConfirming,
isConfirmed,
writeContract,
writeContract: writeContractWithTxPrep,
};
}
17 changes: 14 additions & 3 deletions src/features/wallet/WalletDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,24 @@ import { useStakingRewards } from 'src/features/staking/rewards/useStakingReward
import { useStakingBalances } from 'src/features/staking/useStakingBalances';
import { shortenAddress } from 'src/utils/addresses';
import { useCopyHandler } from 'src/utils/clipboard';
import { logger } from 'src/utils/logger';
import { useAccount, useDisconnect } from 'wagmi';
import { useBalance, useLockedBalance } from '../account/hooks';

export function WalletDropdown() {
const { address, isConnected } = useAccount();
const { openConnectModal } = useConnectModal();
const { disconnect } = useDisconnect();
const { disconnectAsync } = useDisconnect();

const onDisconnect = async () => {
try {
await disconnectAsync();
} catch (err) {
logger.error('Error disconnecting wallet', err);
// Sometimes a page reload helps handle disconnection issues
window.location.reload();
}
};

return (
<div className="relative flex justify-end">
Expand All @@ -29,7 +40,7 @@ export function WalletDropdown() {
)}
buttonClasses={`${OutlineButtonClassName} pl-1.5 pr-3 all:py-1`}
modal={({ close }) => (
<DropdownContent address={address} disconnect={disconnect} close={close} />
<DropdownContent address={address} disconnect={onDisconnect} close={close} />
)}
modalClasses="p-4"
/>
Expand All @@ -46,7 +57,7 @@ function DropdownContent({
close,
}: {
address: Address;
disconnect: () => void;
disconnect: () => any;
close: () => void;
}) {
const { balance: walletBalance } = useBalance(address);
Expand Down
4 changes: 2 additions & 2 deletions src/utils/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import { useRouter } from 'next/navigation';
import { useEffect, useState } from 'react';
import { toast } from 'react-toastify';

export function usePageInvariant(predicate: any, fallbackPath: string, errorMessage: string) {
export function usePageInvariant(predicate: any, fallbackPath: string, errorMessage?: string) {
const [isMessageShown, setIsMessageShown] = useState(false);
const router = useRouter();
useEffect(() => {
if (!predicate && !isMessageShown) {
setIsMessageShown(true);
toast.error(errorMessage);
if (errorMessage) toast.error(errorMessage);
router.replace(fallbackPath);
}
}, [router, predicate, fallbackPath, errorMessage, isMessageShown]);
Expand Down

0 comments on commit f1864ac

Please sign in to comment.