feat: add optimistic UI update for buy transaction before on-chain confirmation (#571) - #614
Merged
Chucks1093 merged 3 commits intoJul 26, 2026
Conversation
Add optimistic update to immediately reflect pending purchases in the React Query holdings cache before on-chain confirmation. Changes: - Add field to interface - Create hook with onMutate/onError/onSuccess/onSettled lifecycle for optimistic cache updates and rollback - Wire buy flow in LandingPage to use the mutation - Show pending badge (spinner badge + muted opacity) on unconfirmed holdings - Merge cache data with local demo state for holdings display - Mock useWallet in affected test files to support new hook dependencies
mutationFn's body doesn't use creatorId/amount (it's a simulated delay), so destructuring them (even with underscore-prefixed names) tripped @typescript-eslint/no-unused-vars — this project's ESLint config doesn't have an argsIgnorePattern exception for that convention. Dropped the parameter entirely since it's unused.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #571.
Summary
Implements an optimistic UI update pattern for buy transactions so holdings reflect immediately in the UI after a user submits a purchase, rather than waiting for on-chain confirmation.
Changes
src/utils/portfolioValue.utils.tspending?: booleanfield to theHeldKeyPositioninterface to support optimistic state tracking per holding entry.src/hooks/useWallet.tsTradeVariablesinterface for typed mutation input (creatorId,amount,priceStroops,price).useTradeMutation(address: string)hook using@tanstack/react-queryuseMutation:mutationFn: Simulates on-chain transaction (900ms delay placeholder, swappable for real contract call).onMutate: Cancels in-flight refetches, snapshots the previous holdings cache, then optimistically updates the cache with the new quantity andpending: true. If the creator is not yet held, a new entry is created.onError: Rolls back to the previous cache snapshot and displays error toast viagetSignatureErrorMessage.onSuccess: Removes thependingflag from the cache and shows a success toast with the amount.onSettled: Invalidates the holdings query to sync with server state after completion.<HeldKeyPosition[]>touseWalletHoldings.src/pages/LandingPage.tsxtradeMutation.mutateAsync(...)instead of local state simulation.heldKeyPositionsmemo merges React Query cache data (with pending state) with local demo holdings, falling back to local state when the cache is empty.opacity-60) whenpending: true.Test files (4 files)
vi.mock("@/hooks/useWallet")inLandingPage.holdings.test.tsx,LandingPage.holdingsCount.integration.test.tsx,LandingPage.holdingsEmptyState.test.tsx, andLandingPage.apiErrorToast.integration.test.tsxto provide mockuseTradeMutationanduseWalletHoldingssince these tests renderLandingPagewithout aQueryClientProvider.Acceptance Criteria
onMutate)onSettledinvalidates the query)onErrorrestores previous cache snapshot)Notes
mutationFncurrently uses a placeholder 900ms delay. Replace with the real contract interaction when available.