Skip to content

Comments

Ui minor fixes, and false failed transaction fix on feat/PRO-3681/transaction-status-pulse#422

Merged
RanaBug merged 3 commits intostagingfrom
feat/PRO-3681/transaction-status-pulse
Oct 6, 2025
Merged

Ui minor fixes, and false failed transaction fix on feat/PRO-3681/transaction-status-pulse#422
RanaBug merged 3 commits intostagingfrom
feat/PRO-3681/transaction-status-pulse

Conversation

@RanaBug
Copy link
Collaborator

@RanaBug RanaBug commented Oct 3, 2025

Description

  • Ui minor fixes, and false failed transaction fix

How Has This Been Tested?

  • Existing Unit Tests and Manual Testing

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Summary by CodeRabbit

  • Bug Fixes

    • Added a short grace window to transaction status handling to avoid premature failures when on-chain activity is detected.
    • Consistent, compact gas fee formatting in Sell preview and status messages.
    • Fixed USD spacing and adjusted transaction step outcomes for buy vs. sell flows.
  • Style

    • Darker error background and full-opacity technical details.
    • Aligned token info visuals for better centering.
    • Confirm button disables and shows “Estimating Gas…” with a spinner during gas estimation/execution.
  • Refactor

    • Internal logic streamlined to keep UI state and status transitions consistent.

@RanaBug RanaBug requested a review from IAmKio October 3, 2025 17:30
@RanaBug RanaBug self-assigned this Oct 3, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 3, 2025

Walkthrough

Adds refs and a 10s grace window to HomeScreen polling to delay failures when an on‑chain tx hash appears; adjusts ResourceLock step logic by isBuy in utils; updates Sell preview gas formatting and button state during gas estimation; minor UI styling and test/mocks updates.

Changes

Cohort / File(s) Summary
Transaction polling / HomeScreen
src/apps/pulse/components/App/HomeScreen.tsx
Adds blockchainTxHashRef and failureGraceExpiryRef; resets refs on start; when polling observes a tx hash, mirrors it to ref/state and starts a 10s grace window; defers premature failure handling while grace window active; couples with hasSeenSuccess flow.
Transaction step logic / utils
src/apps/pulse/utils/utils.tsx
ResourceLock step transitions now depend on isBuy: for buys ResourceLock can be completed/failed depending on flags; for sells it becomes inactive; completed/failed step handling adjusted.
Sell preview UI
src/apps/pulse/components/Sell/PreviewSell.tsx
Gas fee formatting switched to formatExponentialSmallNumber(limitDigitsNumber(parseFloat(...))) when available (fallback "≈ 0.00"); Confirm button disabled/styled and shows "Estimating Gas..." + spinner while isEstimatingGas; spinner also shown during execution.
Sell preview tests / mocks
src/apps/pulse/components/Sell/tests/PreviewSell.test.tsx
Mocks updated for formatExponentialSmallNumber (returns input string) and extended useTransactionKit mock (batch/remove, sendBatches resolves with userOpHash); test assertions updated to new gas formatting (e.g., "≈ 1 ETH").
Transaction UI tweaks
src/apps/pulse/components/Transaction/TransactionDetails.tsx, src/apps/pulse/components/Transaction/TransactionErrorBox.tsx, src/apps/pulse/components/Transaction/TransactionInfo.tsx
Removed extra space in USD display; added items-center to token-info for vertical alignment; increased error box background opacity (from /10 to /5) and set technical details to full opacity; gas fee display wrapped in an IIFE (no behaviour change).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant UI as HomeScreen
  participant Poller as StatusPoller
  participant Chain as Blockchain
  participant Refs as Local Refs/State

  UI->>Poller: startPolling(txId)
  loop every N seconds
    Poller->>Chain: fetchStatus(txId)
    Chain-->>Poller: { status, txHash? }
    alt txHash present
      Poller->>Refs: set blockchainTxHashRef, set failureGraceExpiryRef = now+10s
      Poller->>UI: mirror txHash to state (first observation sets hasSeenHash)
    end
    alt status == success
      Poller->>UI: dispatch Success (update state + hasSeenSuccess)
    else status == failed and blockchainTxHashRef exists and now < failureGraceExpiryRef
      Note right of Poller: defer final failure (within grace window)
      Poller-->>UI: skip failure dispatch
    else status == failed
      Poller->>UI: dispatch Failure
    end
  end
Loading
sequenceDiagram
  autonumber
  participant Flow as Transaction Flow
  participant Steps as Steps Engine (utils)

  rect rgba(230,245,255,0.6)
  note over Flow,Steps: On Success / Completed computation
  Flow->>Steps: computeSteps(isBuy=true/false)
  alt isBuy
    Steps->>Steps: ResourceLock = completed
  else
    Steps->>Steps: ResourceLock = inactive
  end
  end

  rect rgba(255,240,230,0.6)
  note over Flow,Steps: On Failure
  Flow->>Steps: computeSteps(isBuy=true/false, flags)
  alt isBuy
    alt isResourceLockFailed
      Steps->>Steps: ResourceLock = failed (or inactive for completed step)
    else
      Steps->>Steps: ResourceLock = completed
    end
  else
    Steps->>Steps: ResourceLock = inactive
  end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • IAmKio
  • mightyboothkl

Poem

I thump my paw — a hash appears, hold fast,
Ten seconds’ grace to let the truth come past.
Gas hums soft, the button bides its light,
Steps split gentle — buy or sell, all right.
Hop, confirm — the rabbit cheers tonight! 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title Check ⚠️ Warning The pull request title includes branch information and does not concisely describe the main change, combining minor UI fixes with a false failure transaction fix while referencing the feature branch, which adds noise and reduces clarity. Rename the title to a single concise sentence focusing on the key change, such as “Fix false failed transactions and apply minor UI adjustments,” and remove the branch reference to improve clarity.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed The pull request description follows the repository template by including the description summary, testing details, screenshots section, and types of changes, providing sufficient information to understand the updates and how they were tested.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/PRO-3681/transaction-status-pulse

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Oct 3, 2025

Deploying x with  Cloudflare Pages  Cloudflare Pages

Latest commit: d214c3e
Status: ✅  Deploy successful!
Preview URL: https://d772d4f9.x-e62.pages.dev
Branch Preview URL: https://feat-pro-3681-transaction-st.x-e62.pages.dev

View logs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/apps/pulse/components/Sell/PreviewSell.tsx (1)

363-367: Consider extracting the gas fee formatting logic.

The gas fee formatting pattern formatExponentialSmallNumber(limitDigitsNumber(parseFloat(gasCostNative))) is duplicated at lines 670-671. Extracting this into a helper function would improve maintainability.

For example, add a helper function at the top of the component:

+const formatGasFee = (gasCostNative: string | undefined, nativeTokenSymbol: string | undefined): string => {
+  return gasCostNative && nativeTokenSymbol
+    ? `≈ ${formatExponentialSmallNumber(limitDigitsNumber(parseFloat(gasCostNative)))} ${nativeTokenSymbol}`
+    : '≈ 0.00';
+};
+
 const PreviewSell = (props: PreviewSellProps) => {

Then simplify both usages:

-            const gasFeeString =
-              gasCostNative && nativeTokenSymbol
-                ? `≈ ${formatExponentialSmallNumber(limitDigitsNumber(parseFloat(gasCostNative)))} ${nativeTokenSymbol}`
-                : '≈ 0.00';
+            const gasFeeString = formatGasFee(gasCostNative, nativeTokenSymbol);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1931973 and e5c7197.

⛔ Files ignored due to path filters (3)
  • src/apps/pulse/components/Sell/tests/__snapshots__/PreviewSell.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pulse/components/Transaction/tests/__snapshots__/TransactionDetails.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pulse/components/Transaction/tests/__snapshots__/TransactionErrorBox.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (7)
  • src/apps/pulse/components/App/HomeScreen.tsx (1 hunks)
  • src/apps/pulse/components/Sell/PreviewSell.tsx (4 hunks)
  • src/apps/pulse/components/Sell/tests/PreviewSell.test.tsx (3 hunks)
  • src/apps/pulse/components/Transaction/TransactionDetails.tsx (2 hunks)
  • src/apps/pulse/components/Transaction/TransactionErrorBox.tsx (2 hunks)
  • src/apps/pulse/components/Transaction/TransactionInfo.tsx (1 hunks)
  • src/apps/pulse/utils/utils.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/apps/pulse/components/Sell/PreviewSell.tsx (1)
src/utils/number.tsx (2)
  • formatExponentialSmallNumber (119-149)
  • limitDigitsNumber (42-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: lint
  • GitHub Check: unit-tests
  • GitHub Check: build
🔇 Additional comments (4)
src/apps/pulse/components/Sell/PreviewSell.tsx (1)

8-11: LGTM!

The import of formatExponentialSmallNumber and limitDigitsNumber utilities is appropriate for formatting gas fees with proper handling of exponential notation and digit limiting.

src/apps/pulse/components/Sell/tests/PreviewSell.test.tsx (3)

37-37: LGTM!

The mock for formatExponentialSmallNumber correctly returns the input as a string, aligning with the new gas formatting logic in the component.


52-63: LGTM!

The extended mocks for batch (with remove function) and sendBatches (with success response) correctly support the new transaction flow and batch cleanup logic in PreviewSell.


198-198: LGTM!

The test assertion update from "≈ 1.000000 ETH" to "≈ 1 ETH" correctly reflects the new gas fee formatting behavior using formatExponentialSmallNumber and limitDigitsNumber.

@github-actions github-actions bot temporarily deployed to Preview (feat/PRO-3681/transaction-status-pulse) October 6, 2025 11:16 Inactive
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/apps/pulse/components/Sell/PreviewSell.tsx (2)

363-368: Extract duplicate gas fee formatting into a helper function.

The gas fee formatting logic appears twice (lines 364–367 and lines 670–672) with identical computations. Extracting this into a helper function improves maintainability and reduces the risk of inconsistencies.

Add a helper function near the top of the component:

const formatGasFeeDisplay = (
  gasCostNative: string | undefined,
  nativeTokenSymbol: string | undefined
): string => {
  return gasCostNative && nativeTokenSymbol
    ? `≈ ${formatExponentialSmallNumber(limitDigitsNumber(parseFloat(gasCostNative)))} ${nativeTokenSymbol}`
    : '≈ 0.00';
};

Then replace lines 364–367 with:

-            const gasFeeString =
-              gasCostNative && nativeTokenSymbol
-                ? `≈ ${formatExponentialSmallNumber(limitDigitsNumber(parseFloat(gasCostNative)))} ${nativeTokenSymbol}`
-                : '≈ 0.00';
+            const gasFeeString = formatGasFeeDisplay(gasCostNative, nativeTokenSymbol);

And replace lines 669–674 with:

           'Gas fee',
-          (() => {
-            const gasFeeDisplay = gasCostNative
-              ? `≈ ${formatExponentialSmallNumber(limitDigitsNumber(parseFloat(gasCostNative)))} ${nativeTokenSymbol}`
-              : '≈ 0.00';
-            return gasFeeDisplay;
-          })(),
+          formatGasFeeDisplay(gasCostNative, nativeTokenSymbol),
           false,

Also applies to: 669-674


711-715: Consider showing "Executing..." instead of "Confirm" during transaction execution.

When isExecuting is true but isEstimatingGas is false, the button displays a spinner with the label "Confirm" (line 714). This may confuse users, as "Confirm" typically indicates a clickable action rather than an in-progress operation. Changing the label to "Executing..." or similar would improve clarity.

Apply this diff:

             {isExecuting || isEstimatingGas ? (
               <div className="flex items-center justify-center gap-2">
                 <TailSpin color="#FFFFFF" height={20} width={20} />
-                <span>{isEstimatingGas ? 'Estimating Gas...' : 'Confirm'}</span>
+                <span>{isEstimatingGas ? 'Estimating Gas...' : 'Executing...'}</span>
               </div>
             ) : (
               <>Confirm</>
             )}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e5c7197 and 5f38fbc.

⛔ Files ignored due to path filters (2)
  • src/apps/pillarx-app/components/TokenMarketDataRow/tests/__snapshots__/LeftColumnTokenMarketDataRow.test.tsx.snap is excluded by !**/*.snap
  • src/apps/pillarx-app/components/TokensWithMarketDataTile/test/__snapshots__/TokensWithMarketDataTile.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (2)
  • src/apps/pulse/components/App/HomeScreen.tsx (3 hunks)
  • src/apps/pulse/components/Sell/PreviewSell.tsx (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/apps/pulse/components/Sell/PreviewSell.tsx (1)
src/utils/number.tsx (2)
  • formatExponentialSmallNumber (119-149)
  • limitDigitsNumber (42-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit-tests
  • GitHub Check: lint
  • GitHub Check: build

@github-actions github-actions bot temporarily deployed to Preview (feat/PRO-3681/transaction-status-pulse) October 6, 2025 12:28 Inactive
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/apps/pulse/components/App/HomeScreen.tsx (1)

657-673: Verify grace window interaction with failure timeouts.

When a blockchain hash arrives after a failure timeout has already been scheduled (e.g., status reported as 'Reverted' before hash appears), the grace window prevents new timeouts from being scheduled but doesn't cancel the existing one. This means:

  • t=0s: Status 'Reverted', no hash → updateStatusWithDelay schedules failure timeout at t=10s
  • t=2s: Hash arrives → grace initialized (expires at t=12s), early return prevents new timeout
  • t=10s: Original timeout fires → marks transaction as failed (if hasSeenSuccessRef still false)
  • t=12s: Grace window expires, but transaction already marked as failed

Is this intended? If the grace window should give the transaction 10s from when the hash is observed (not from the first failure), consider canceling any pending failureTimeoutId when initializing the grace window at line 653:

 if (firstObservation && failureGraceExpiryRef.current == null) {
   failureGraceExpiryRef.current = Date.now() + 10000; // start grace on first hash
+  if (failureTimeoutId) {
+    clearTimeout(failureTimeoutId);
+    setFailureTimeoutId(null);
+  }
 }

Additionally, the comment at line 667 ("skip once immediately when hash first observed") is misleading because:

  1. This block only executes when status is failed (line 660), not when hash first observed
  2. The skip is not once—it's for the entire 10s grace period (line 669-670)
  3. Grace is typically initialized at line 653 when hash first observed, making lines 665-667 a defensive fallback
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f38fbc and d214c3e.

📒 Files selected for processing (1)
  • src/apps/pulse/components/App/HomeScreen.tsx (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit-tests
  • GitHub Check: lint
  • GitHub Check: build
🔇 Additional comments (6)
src/apps/pulse/components/App/HomeScreen.tsx (6)

160-161: LGTM: Refs properly avoid stale closures.

The use of refs for blockchainTxHashRef and failureGraceExpiryRef correctly addresses the stale closure issue mentioned in previous reviews, ensuring the polling effect always reads fresh values without requiring them in the dependency array.


291-292: LGTM: Refs properly reset for each transaction.

Resetting both blockchainTxHashRef and failureGraceExpiryRef alongside other transaction state ensures each transaction starts with a clean slate.


635-635: LGTM: Ref mirrors state for timeout callbacks.

Setting hasSeenSuccessRef.current = true ensures that failure timeout callbacks (which check this ref at line 416) see the fresh success status and abort correctly.


639-645: LGTM: Defensive dual-check pattern.

Checking both hasSeenSuccess state and hasSeenSuccessRef.current provides defense-in-depth against edge cases and ensures failures are suppressed once success is observed, regardless of state/ref sync timing.


647-655: LGTM: Hash extraction now happens before failure check.

Moving the hash extraction block before the failure guard (lines 657-673) correctly addresses the race condition identified in previous reviews, ensuring the ref is populated before the grace-window logic evaluates it.


675-676: LGTM: Status update happens after all guards.

Calling updateStatusWithDelay after the grace window logic ensures that status updates only occur when appropriate, maintaining the existing delayed display behavior.

@RanaBug RanaBug merged commit d1a8986 into staging Oct 6, 2025
6 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Oct 23, 2025
3 tasks
@coderabbitai coderabbitai bot mentioned this pull request Nov 5, 2025
3 tasks
@coderabbitai coderabbitai bot mentioned this pull request Nov 13, 2025
3 tasks
@coderabbitai coderabbitai bot mentioned this pull request Nov 26, 2025
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants