diff --git a/packages/web/src/app/(authenticated)/dashboard/savings/page-wrapper.tsx b/packages/web/src/app/(authenticated)/dashboard/savings/page-wrapper.tsx index f1b7dbd06..5dfa24dd2 100644 --- a/packages/web/src/app/(authenticated)/dashboard/savings/page-wrapper.tsx +++ b/packages/web/src/app/(authenticated)/dashboard/savings/page-wrapper.tsx @@ -152,6 +152,7 @@ export default function SavingsPageWrapper({ // Base vaults configuration const BASE_VAULTS = BASE_USDC_VAULTS; const baseVaultAddresses = BASE_VAULTS.map((v) => v.address); + const trpcUtils = trpc.useUtils(); // Fetch multi-vault stats const realVaultStatsMany = trpc.earn.statsByVault.useQuery( @@ -401,6 +402,44 @@ export default function SavingsPageWrapper({ }); }; + const handleVaultActionSuccess = () => { + closeModal(); + + if (!safeAddress || isDemoMode) { + return; + } + + const refreshPromises: Promise[] = [ + trpcUtils.earn.stats.invalidate({ safeAddress }), + trpcUtils.earn.statsByVault.invalidate({ + safeAddress, + vaultAddresses: baseVaultAddresses, + }), + trpcUtils.earn.userPositions.invalidate({ + userSafe: safeAddress, + vaultAddresses: baseVaultAddresses, + }), + trpcUtils.earn.getState.invalidate({ safeAddress }), + trpcUtils.earn.getAutoEarnConfig.invalidate({ safeAddress }), + trpcUtils.earn.getRecentEarnDeposits.invalidate({ + safeAddress, + limit: 5, + }), + ]; + + refreshPromises.push(realVaultStats.refetch()); + refreshPromises.push(realVaultStatsMany.refetch()); + refreshPromises.push(realUserPositions.refetch()); + + void (async () => { + try { + await Promise.all(refreshPromises); + } catch (error) { + console.error('Failed to refresh savings data after vault action:', error); + } + })(); + }; + return (
{/* Header Section */} @@ -914,7 +953,7 @@ export default function SavingsPageWrapper({ )} @@ -936,7 +975,7 @@ export default function SavingsPageWrapper({ )} diff --git a/packages/web/src/app/(authenticated)/dashboard/tools/earn-module/components/deposit-earn-card.tsx b/packages/web/src/app/(authenticated)/dashboard/tools/earn-module/components/deposit-earn-card.tsx index da72080ab..c578c1bad 100644 --- a/packages/web/src/app/(authenticated)/dashboard/tools/earn-module/components/deposit-earn-card.tsx +++ b/packages/web/src/app/(authenticated)/dashboard/tools/earn-module/components/deposit-earn-card.tsx @@ -106,6 +106,8 @@ export function DepositEarnCard({ safeAddress, vaultAddress, onDepositSuccess }: const currentAllowance = allowanceData ? BigInt(allowanceData.allowance) : 0n; const needsApproval = amountInSmallestUnit > currentAllowance; + let latestTxHash: `0x${string}` | undefined; + try { // Step 1: Check requirements setTransactionState({ step: 'checking' }); @@ -125,21 +127,31 @@ export function DepositEarnCard({ safeAddress, vaultAddress, onDepositSuccess }: args: [vaultAddress, amountInSmallestUnit] }); - const approvalTxHash = await sendTxViaRelay([{ - to: USDC_ADDRESS, - value: '0', - data: approveData, - }], 300_000n); + const approvalTxHash = await sendTxViaRelay([ + { + to: USDC_ADDRESS, + value: '0', + data: approveData, + }, + ], 300_000n); if (!approvalTxHash) throw new Error('Approval transaction failed'); - setTransactionState({ - step: 'waiting-approval', - txHash: approvalTxHash + setTransactionState({ + step: 'waiting-approval', + txHash: approvalTxHash, }); - // Wait for approval to be mined - await new Promise(resolve => setTimeout(resolve, 7000)); + // Wait for approval confirmation before proceeding + const approvalReceipt = await publicClient.waitForTransactionReceipt({ + hash: approvalTxHash, + confirmations: 1, + }); + + if (approvalReceipt.status !== 'success') { + throw new Error('Approval transaction reverted on Base'); + } + await refetchAllowance(); } @@ -175,27 +187,38 @@ export function DepositEarnCard({ safeAddress, vaultAddress, onDepositSuccess }: args: [amountInSmallestUnit, safeAddress] }); - const depositTxHash = await sendTxViaRelay([{ - to: vaultAddress, - value: '0', - data: depositData, - }], 500_000n); + const depositTxHash = await sendTxViaRelay([ + { + to: vaultAddress, + value: '0', + data: depositData, + }, + ], 500_000n); if (!depositTxHash) throw new Error('Deposit transaction failed'); - setTransactionState({ - step: 'waiting-deposit', - txHash: depositTxHash + latestTxHash = depositTxHash; + + setTransactionState({ + step: 'waiting-deposit', + txHash: depositTxHash, }); - // Wait for deposit to be mined - await new Promise(resolve => setTimeout(resolve, 7000)); + // Wait for deposit confirmation on Base + const receipt = await publicClient.waitForTransactionReceipt({ + hash: depositTxHash, + confirmations: 1, + }); + + if (receipt.status !== 'success') { + throw new Error('Deposit transaction reverted on Base'); + } // Success! - setTransactionState({ - step: 'success', + setTransactionState({ + step: 'success', txHash: depositTxHash, - depositedAmount: amount + depositedAmount: amount, }); // Reset form and refetch data @@ -209,9 +232,15 @@ export function DepositEarnCard({ safeAddress, vaultAddress, onDepositSuccess }: } catch (error) { console.error('Transaction error:', error); - setTransactionState({ - step: 'error', - errorMessage: error instanceof Error ? error.message : 'Transaction failed' + const baseMessage = + error instanceof Error ? error.message : 'Transaction failed'; + const errorMessage = latestTxHash + ? `${baseMessage}. Check BaseScan for hash ${latestTxHash}` + : baseMessage; + setTransactionState({ + step: 'error', + txHash: latestTxHash, + errorMessage, }); } }; @@ -287,7 +316,7 @@ export function DepositEarnCard({ safeAddress, vaultAddress, onDepositSuccess }: Step 1 of 2: Approving USDC
{transactionState.txHash && ( - )} + {transactionState.step === 'waiting-approval' && ( +

+ Approval submitted. Waiting for confirmation on Base... +

+ )} )} - + {(transactionState.step === 'depositing' || transactionState.step === 'waiting-deposit') && (
@@ -307,7 +341,7 @@ export function DepositEarnCard({ safeAddress, vaultAddress, onDepositSuccess }: Step 2 of 2: Depositing USDC
{transactionState.txHash && ( - )} + {transactionState.step === 'waiting-deposit' && ( +

+ Transaction submitted. Waiting for confirmation on Base... +

+ )}
)} - +

Please wait while your transaction is being processed on Base network