Skip to content

Commit

Permalink
notifications in a much better state now
Browse files Browse the repository at this point in the history
  • Loading branch information
0age committed Dec 10, 2024
1 parent 8b6904b commit 68b85f5
Show file tree
Hide file tree
Showing 4 changed files with 199 additions and 58 deletions.
16 changes: 4 additions & 12 deletions frontend/src/components/Transfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ export function Transfer({
amount: '',
});

const { allocatedTransfer, isPending: isTransferLoading } =
const { allocatedTransfer, isConfirming: isTransferLoading } =
useAllocatedTransfer();
const { allocatedWithdrawal, isPending: isWithdrawalPending } =
const { allocatedWithdrawal, isConfirming: isWithdrawalConfirming } =
useAllocatedWithdrawal();
const { requestAllocation } = useRequestAllocation();
const { showNotification } = useNotification();
Expand Down Expand Up @@ -420,14 +420,6 @@ export function Transfer({
await allocatedTransfer(transfer);
}

showNotification({
type: 'success',
title: isWithdrawal ? 'Withdrawal Submitted' : 'Transfer Submitted',
message: `Successfully submitted ${isWithdrawal ? 'withdrawal' : 'transfer'} of ${
formData.amount
} ${isWithdrawal ? tokenSymbol : tokenName.resourceLockSymbol}`,
});

// Reset form and close
setFormData({
expires: '',
Expand Down Expand Up @@ -726,11 +718,11 @@ export function Transfer({
<button
type="submit"
disabled={
!isFormValid || isTransferLoading || isWithdrawalPending
!isFormValid || isTransferLoading || isWithdrawalConfirming
}
className="w-full py-2 px-4 bg-[#00ff00] text-gray-900 rounded-lg font-medium hover:bg-[#00dd00] transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
>
{isTransferLoading || isWithdrawalPending ? (
{isTransferLoading || isWithdrawalConfirming ? (
<span className="flex items-center justify-center">
<svg
className="animate-spin -ml-1 mr-3 h-5 w-5 text-gray-900"
Expand Down
112 changes: 97 additions & 15 deletions frontend/src/hooks/useAllocatedTransfer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { useWriteContract, useChainId, useAccount } from 'wagmi';
import {
useWriteContract,
useChainId,
useAccount,
usePublicClient,
useWaitForTransactionReceipt,
} from 'wagmi';
import { type Chain } from 'viem';
import {
COMPACT_ABI,
Expand All @@ -16,6 +22,7 @@ import {
base,
baseSepolia,
} from 'viem/chains';
import { useState } from 'react';

const chains: Record<number, Chain> = {
[mainnet.id]: mainnet,
Expand All @@ -30,10 +37,44 @@ const chains: Record<number, Chain> = {
export function useAllocatedTransfer() {
const chainId = useChainId();
const { address } = useAccount();
const { writeContract, isPending } = useWriteContract();
const publicClient = usePublicClient();
const [hash, setHash] = useState<`0x${string}` | undefined>();
const { writeContractAsync } = useWriteContract({
mutation: {
onError: (error) => {
if (
error instanceof Error &&
!error.message.toLowerCase().includes('user rejected')
) {
showNotification({
type: 'error',
title: 'Transaction Failed',
message: error.message,
autoHide: true,
});
}
},
},
});
const { showNotification } = useNotification();

const { isLoading: isConfirming, isSuccess: isConfirmed } =
useWaitForTransactionReceipt({
hash,
onReplaced: (replacement) => {
showNotification({
type: 'info',
title: 'Transaction Replaced',
message: `Transaction was ${replacement.reason}. Waiting for new transaction...`,
txHash: replacement.transaction.hash,
autoHide: false,
});
},
});

const allocatedTransfer = async (transferPayload: BasicTransfer) => {
if (!publicClient) throw new Error('Public client not available');

if (!isSupportedChain(chainId)) {
throw new Error('Unsupported chain');
}
Expand All @@ -43,37 +84,78 @@ export function useAllocatedTransfer() {
throw new Error('Chain configuration not found');
}

// Generate a temporary transaction ID for linking notifications
const tempTxId = `pending-${Date.now()}`;

// Format the amount for display
const displayAmount = transferPayload.amount
? `${Number(transferPayload.amount) / 10 ** 18} ETH`
: 'tokens';

showNotification({
type: 'info',
title: 'Initiating Transfer',
message: `Waiting for transaction submission of ${displayAmount}...`,
stage: 'initiated',
txHash: tempTxId,
autoHide: false,
});

try {
const hash = await writeContract({
const newHash = await writeContractAsync({
address: COMPACT_ADDRESS as `0x${string}`,
abi: [COMPACT_ABI.find((x) => x.name === 'allocatedTransfer')] as const,
functionName: 'allocatedTransfer',
args: [transferPayload],
account: address,
chain,
});

showNotification({
type: 'success',
title: 'Transaction Submitted',
message: 'Your transfer transaction has been submitted.',
message: 'Waiting for confirmation...',
stage: 'submitted',
txHash: newHash,
autoHide: false,
});

return hash;
} catch (error) {
console.error('Transfer error:', error);
showNotification({
type: 'error',
title: 'Transaction Failed',
message:
error instanceof Error ? error.message : 'Failed to submit transfer',
setHash(newHash);

// Wait for confirmation
const receipt = await publicClient.waitForTransactionReceipt({
hash: newHash,
});
if (receipt.status === 'success') {
showNotification({
type: 'success',
title: 'Transfer Confirmed',
message: `Successfully transferred ${displayAmount}`,
stage: 'confirmed',
txHash: newHash,
autoHide: true,
});
}

return newHash;
} catch (error) {
if (
error instanceof Error &&
error.message.toLowerCase().includes('user rejected')
) {
showNotification({
type: 'error',
title: 'Transaction Rejected',
message: 'You rejected the transaction',
txHash: tempTxId,
autoHide: true,
});
}
throw error;
}
};

return {
allocatedTransfer,
isPending,
isConfirming,
isConfirmed,
};
}
114 changes: 97 additions & 17 deletions frontend/src/hooks/useAllocatedWithdrawal.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { useWriteContract, useChainId, useAccount } from 'wagmi';
import {
useWriteContract,
useChainId,
useAccount,
usePublicClient,
useWaitForTransactionReceipt,
} from 'wagmi';
import { type Chain } from 'viem';
import {
COMPACT_ABI,
Expand All @@ -16,6 +22,7 @@ import {
base,
baseSepolia,
} from 'viem/chains';
import { useState } from 'react';

const chains: Record<number, Chain> = {
[mainnet.id]: mainnet,
Expand All @@ -30,10 +37,44 @@ const chains: Record<number, Chain> = {
export function useAllocatedWithdrawal() {
const chainId = useChainId();
const { address } = useAccount();
const { writeContract, isPending } = useWriteContract();
const publicClient = usePublicClient();
const [hash, setHash] = useState<`0x${string}` | undefined>();
const { writeContractAsync } = useWriteContract({
mutation: {
onError: (error) => {
if (
error instanceof Error &&
!error.message.toLowerCase().includes('user rejected')
) {
showNotification({
type: 'error',
title: 'Transaction Failed',
message: error.message,
autoHide: true,
});
}
},
},
});
const { showNotification } = useNotification();

const { isLoading: isConfirming, isSuccess: isConfirmed } =
useWaitForTransactionReceipt({
hash,
onReplaced: (replacement) => {
showNotification({
type: 'info',
title: 'Transaction Replaced',
message: `Transaction was ${replacement.reason}. Waiting for new transaction...`,
txHash: replacement.transaction.hash,
autoHide: false,
});
},
});

const allocatedWithdrawal = async (transferPayload: BasicTransfer) => {
if (!publicClient) throw new Error('Public client not available');

if (!isSupportedChain(chainId)) {
throw new Error('Unsupported chain');
}
Expand All @@ -43,41 +84,80 @@ export function useAllocatedWithdrawal() {
throw new Error('Chain configuration not found');
}

// Generate a temporary transaction ID for linking notifications
const tempTxId = `pending-${Date.now()}`;

// Format the amount for display
const displayAmount = transferPayload.amount
? `${Number(transferPayload.amount) / 10 ** 18} ETH`
: 'tokens';

showNotification({
type: 'info',
title: 'Initiating Withdrawal',
message: `Waiting for transaction submission of ${displayAmount}...`,
stage: 'initiated',
txHash: tempTxId,
autoHide: false,
});

try {
const hash = await writeContract({
const newHash = await writeContractAsync({
address: COMPACT_ADDRESS as `0x${string}`,
abi: [
COMPACT_ABI.find((x) => x.name === 'allocatedWithdrawal'),
] as const,
functionName: 'allocatedWithdrawal',
args: [transferPayload],
account: address,
chain,
});

showNotification({
type: 'success',
title: 'Transaction Submitted',
message: 'Your withdrawal transaction has been submitted.',
message: 'Waiting for confirmation...',
stage: 'submitted',
txHash: newHash,
autoHide: false,
});

return hash;
} catch (error) {
console.error('Withdrawal error:', error);
showNotification({
type: 'error',
title: 'Transaction Failed',
message:
error instanceof Error
? error.message
: 'Failed to submit withdrawal',
setHash(newHash);

// Wait for confirmation
const receipt = await publicClient.waitForTransactionReceipt({
hash: newHash,
});
if (receipt.status === 'success') {
showNotification({
type: 'success',
title: 'Withdrawal Confirmed',
message: `Successfully withdrew ${displayAmount}`,
stage: 'confirmed',
txHash: newHash,
autoHide: true,
});
}

return newHash;
} catch (error) {
if (
error instanceof Error &&
error.message.toLowerCase().includes('user rejected')
) {
showNotification({
type: 'error',
title: 'Transaction Rejected',
message: 'You rejected the transaction',
txHash: tempTxId,
autoHide: true,
});
}
throw error;
}
};

return {
allocatedWithdrawal,
isPending,
isConfirming,
isConfirmed,
};
}
15 changes: 1 addition & 14 deletions frontend/src/hooks/useCompact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,22 +373,9 @@ export function useCompact() {
setHash(newHash);

// Wait for confirmation
const receipt = await publicClient.waitForTransactionReceipt({
await publicClient.waitForTransactionReceipt({
hash: newHash,
});
if (receipt.status === 'success') {
showNotification({
type: 'success',
title: 'Forced Withdrawal Executed',
message:
displayAmount && symbol
? `Successfully withdrew ${displayAmount} ${symbol}`
: 'Withdrawal successful',
stage: 'confirmed',
txHash: newHash,
autoHide: true,
});
}

return newHash;
} catch (error) {
Expand Down

0 comments on commit 68b85f5

Please sign in to comment.