Skip to content

PRO-3800-Gas Warning Check On Sell#431

Merged
vignesha22 merged 2 commits intostagingfrom
PRO-3800-Gas-Warning-on-Sell-side
Oct 13, 2025
Merged

PRO-3800-Gas Warning Check On Sell#431
vignesha22 merged 2 commits intostagingfrom
PRO-3800-Gas-Warning-on-Sell-side

Conversation

@vignesha22
Copy link
Contributor

@vignesha22 vignesha22 commented Oct 10, 2025

Description

  • Removed min input amount of sell
  • Added min gas token check on selected token

How Has This Been Tested?

  • Tested Locally

Screenshots (if appropriate):

Screenshot 2025-10-10 at 7 21 25 PM Screenshot 2025-10-10 at 7 21 37 PM

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

  • New Features

    • Enforces a Min. $1 native-token reserve for gas before selling; shows a “Min. $1” warning with chain and native token.
    • Sell button and error states now reflect gas-balance checks to prevent insufficient-gas attempts.
    • Buy and Home now use wallet portfolio balances so UI warnings and balances reflect actual token holdings.
  • Tests

    • Updated tests to cover portfolio-token scenarios and low/no-gas conditions.

@vignesha22 vignesha22 requested review from IAmKio and RanaBug October 10, 2025 13:52
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 10, 2025

Walkthrough

Replaces minAmount checks with a minGasAmount computed from per-wallet portfolio token data passed as a new portfolioTokens prop; HomeScreen now derives and passes portfolioTokens to Buy/Sell, tests updated to supply new shapes, and Sell/Buy use chain/native helpers to enforce a $1 native-token gas minimum.

Changes

Cohort / File(s) Summary of Changes
Sell component
src/apps/pulse/components/Sell/Sell.tsx
Replaced minAmount logic with minGasAmount computed from portfolioTokens and chain/native helpers; added useEffect to determine native token balance/price and set minGasAmount; updated validations, UI messaging (Min. $1 using NativeSymbols/ChainNames), imports, and passed minGasAmount into SellButton notEnoughLiquidity. Added portfolioTokens: PortfolioToken[] prop with default [].
Buy component
src/apps/pulse/components/Buy/Buy.tsx
Switched from converting walletPortfolioData to accepting a portfolioTokens: PortfolioToken[] prop; updated native token lookup, balance/price checks, effects, imports, and BuyProps signature. Tests updated to pass new props.
Home / prop plumbing
src/apps/pulse/components/App/HomeScreen.tsx
Added portfolioTokens state (from convertPortfolioAPIResponseToToken(walletPortfolioData)), effect to populate it, and passed portfolioTokens into Buy and Sell.
Tests — AppWrapper
src/apps/pulse/components/App/tests/AppWrapper.test.tsx
Updated mocked WalletPortfolio response shape: data.data.tokensdata.data.assets; added wallets and balances_length fields in mock; kept outer shape and other mocks consistent.
Tests — Buy
src/apps/pulse/components/Buy/tests/Buy.test.tsx
Added mockPortfolioTokens (and variations like lowBalancePortfolioTokens, noGasPortfolioTokens) and wired portfolioTokens into Buy test props; adjusted test setups and expectations to exercise $1 native-gas scenarios and new prop-driven behavior.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Home as HomeScreen
  participant Wallet as WalletPortfolio API
  participant Conv as convertPortfolioAPIResponseToToken
  participant Buy as Buy.tsx
  participant Sell as Sell.tsx
  participant Chain as Chain Helpers
  participant UI as UI / SellButton

  User->>Home: Open app
  Home->>Wallet: query walletPortfolioData
  Wallet-->>Home: walletPortfolioData
  Home->>Conv: convertPortfolioAPIResponseToToken(walletPortfolioData)
  Conv-->>Home: portfolioTokens
  Home->>Buy: pass portfolioTokens
  Home->>Sell: pass portfolioTokens

  User->>Sell: select token / chain
  Sell->>Chain: getChainId(), isNativeToken()
  Sell->>Sell: compute minGasAmount from portfolioTokens (native price * balance < $1 ?)
  alt minGasAmount true
    Sell->>UI: show "Min. $1 native token" warning
    Sell->>UI: set SellButton.notEnoughLiquidity = true (includes minGasAmount)
  else
    Sell->>UI: normal validation flow
  end

  User->>Buy: select token
  Buy->>Chain: getChainId(), isNativeToken()
  Buy->>Buy: compute/use portfolioTokens for gas checks (similar)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • IAmKio
  • RanaBug

Poem

I hop through chains with pockets light,
A dollar's seed to keep our flight—
I count my gas in tiny hops,
Warn before the last coin drops.
Tap the button, safe and sly—
A bunny guards your gas nearby. 🐰✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
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 (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly captures the primary change by referencing the addition of a gas warning check on the sell side and directly aligns with the pull request’s main update without extraneous details.
Description Check ✅ Passed The pull request description includes all required template sections—Description, How Has This Been Tested, Screenshots, and Types of changes—and provides relevant content for each, clearly summarizing the removal of the minimum input check and the addition of the gas token warning, including illustrative screenshots and marking the change as a bug fix.
✨ 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 PRO-3800-Gas-Warning-on-Sell-side

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 10, 2025

Deploying x with  Cloudflare Pages  Cloudflare Pages

Latest commit: 81602bd
Status: ✅  Deploy successful!
Preview URL: https://f9d7a061.x-e62.pages.dev
Branch Preview URL: https://pro-3800-gas-warning-on-sell.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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7ac9159 and f1f8fdb.

📒 Files selected for processing (1)
  • src/apps/pulse/components/Sell/Sell.tsx (7 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: RanaBug
PR: pillarwallet/x#391
File: src/apps/pulse/components/Sell/Sell.tsx:113-130
Timestamp: 2025-09-09T12:40:15.629Z
Learning: In the Pulse app Sell component, when a user changes/switches tokens, the input amount automatically resets to 0, which means liquidity validation state doesn't become stale when tokens change.
📚 Learning: 2025-09-09T12:40:15.629Z
Learnt from: RanaBug
PR: pillarwallet/x#391
File: src/apps/pulse/components/Sell/Sell.tsx:113-130
Timestamp: 2025-09-09T12:40:15.629Z
Learning: In the Pulse app Sell component, when a user changes/switches tokens, the input amount automatically resets to 0, which means liquidity validation state doesn't become stale when tokens change.

Applied to files:

  • src/apps/pulse/components/Sell/Sell.tsx
🧬 Code graph analysis (1)
src/apps/pulse/components/Sell/Sell.tsx (2)
src/apps/pulse/utils/constants.ts (1)
  • getChainId (28-49)
src/apps/pulse/utils/blockchain.ts (3)
  • isNativeToken (17-18)
  • NativeSymbols (20-27)
  • ChainNames (29-36)
⏰ 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). (2)
  • GitHub Check: lint
  • GitHub Check: unit-tests

Comment on lines 347 to 350
{relayError ||
(notEnoughLiquidity ? 'Not enough balance' : '') ||
(minAmount ? 'Min amount is $1 worth of tokens' : '')}
(minGasAmount && token ? `Min. $1 ${NativeSymbols[token.chainId]} required on ${ChainNames[token.chainId]}` : '')}
</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Handle unmapped native symbols/names in the warning.

When token.chainId isn’t present in NativeSymbols / ChainNames (e.g., Gnosis chainId 100), the UI renders Min. $1 undefined required on undefined, which is a broken user-facing message. Please add sensible fallbacks (or extend the maps) so we never display undefined to users.

-                    (minGasAmount && token ? `Min. $1 ${NativeSymbols[token.chainId]} required on ${ChainNames[token.chainId]}` : '')}
+                    (minGasAmount && token
+                      ? `Min. $1 ${NativeSymbols[token.chainId] ?? 'native token'} required on ${
+                          ChainNames[token.chainId] ?? 'this chain'
+                        }`
+                      : '')}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{relayError ||
(notEnoughLiquidity ? 'Not enough balance' : '') ||
(minAmount ? 'Min amount is $1 worth of tokens' : '')}
(minGasAmount && token ? `Min. $1 ${NativeSymbols[token.chainId]} required on ${ChainNames[token.chainId]}` : '')}
</div>
{relayError ||
(notEnoughLiquidity ? 'Not enough balance' : '') ||
(minGasAmount && token
? `Min. $1 ${NativeSymbols[token.chainId] ?? 'native token'} required on ${ChainNames[token.chainId] ?? 'this chain'}`
: '')}
</div>

}
};

useEffect(() => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I have seen this logic somewhere else. Is it worth doing that call higher up and pass it on to the components? Since it is used in Buy as well I believe?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah right

@@ -127,14 +159,8 @@

if (input && token) {
const inputAmount = parseFloat(input);
Copy link
Collaborator

Choose a reason for hiding this comment

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

why was minAmount removed completely from the logic? I have seen similar logic in buy, please make sure the logic are the same in both buy and sell

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes but that was only asked from me to revert the changes and add only gas token check

Copy link
Collaborator

Choose a reason for hiding this comment

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

OK I see

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

♻️ Duplicate comments (1)
src/apps/pulse/components/Sell/Sell.tsx (1)

348-352: Handle unmapped native symbols/names in the warning.

When token.chainId isn't present in NativeSymbols / ChainNames (e.g., Gnosis chainId 100), the UI renders Min. $1 undefined required on undefined, which is a broken user-facing message. Please add sensible fallbacks (or extend the maps) so we never display undefined to users.

Apply this diff:

                   (minGasAmount && token
-                     ? `Min. $1 ${NativeSymbols[token.chainId]} required on ${ChainNames[token.chainId]}`
+                     ? `Min. $1 ${NativeSymbols[token.chainId] ?? 'native token'} required on ${
+                         ChainNames[token.chainId] ?? 'this chain'
+                       }`
                      : '')}
🧹 Nitpick comments (3)
src/apps/pulse/components/App/HomeScreen.tsx (1)

741-749: Add error handling for portfolio conversion.

If convertPortfolioAPIResponseToToken throws an exception, portfolioTokens remains empty, which could cause downstream components (Buy/Sell) to display incorrect warnings or block functionality.

Apply this diff to add error handling:

 useEffect(() => {
   if (!walletPortfolioData) return;

-  const tokens = convertPortfolioAPIResponseToToken(
-    walletPortfolioData.result.data
-  );
-
-  setPortfolioTokens(tokens);
+  try {
+    const tokens = convertPortfolioAPIResponseToToken(
+      walletPortfolioData.result.data
+    );
+    setPortfolioTokens(tokens);
+  } catch (error) {
+    console.error('Failed to convert portfolio data:', error);
+    setPortfolioTokens([]);
+  }
 }, [walletPortfolioData]);
src/apps/pulse/components/Buy/Buy.tsx (1)

176-180: Update console warning to reflect portfolioTokens check.

The warning message "No wallet portfolio data" is now misleading since the condition checks portfolioTokens instead of walletPortfolioData.

Apply this diff:

-  if (!portfolioTokens || portfolioTokens.length === 0) {
-    console.warn('No wallet portfolio data');
+  if (!portfolioTokens || portfolioTokens.length === 0) {
+    console.warn('No portfolio tokens available');
     return;
   }
src/apps/pulse/components/Sell/Sell.tsx (1)

130-150: Guard against zero/null values in gas amount calculation.

At line 145, if either nativeToken.price or nativeToken.balance is explicitly 0 (not just falsy), the calculation evaluates to 0 < 1, incorrectly triggering the minGasAmount warning even when the user might have a native token with zero price data (due to a temporary API issue) or legitimately zero balance.

Consider being more explicit about the check to avoid false positives:

   const nativeToken = portfolioTokens.find(
     (t) =>
       Number(getChainId(t.blockchain as MobulaChainNames)) ===
         token.chainId && isNativeToken(t.contract)
   );
   if (!nativeToken) {
     setMinGasAmount(true);
     return;
   }
-  if ((nativeToken?.price || 0) * (nativeToken?.balance || 0) < 1) {
+  const nativeTokenValue = (nativeToken.price ?? 0) * (nativeToken.balance ?? 0);
+  if (nativeTokenValue < 1) {
     setMinGasAmount(true);
   } else {
     setMinGasAmount(false);
   }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f1f8fdb and 81602bd.

📒 Files selected for processing (5)
  • src/apps/pulse/components/App/HomeScreen.tsx (5 hunks)
  • src/apps/pulse/components/App/tests/AppWrapper.test.tsx (1 hunks)
  • src/apps/pulse/components/Buy/Buy.tsx (6 hunks)
  • src/apps/pulse/components/Buy/tests/Buy.test.tsx (3 hunks)
  • src/apps/pulse/components/Sell/Sell.tsx (8 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-09T12:40:15.629Z
Learnt from: RanaBug
PR: pillarwallet/x#391
File: src/apps/pulse/components/Sell/Sell.tsx:113-130
Timestamp: 2025-09-09T12:40:15.629Z
Learning: In the Pulse app Sell component, when a user changes/switches tokens, the input amount automatically resets to 0, which means liquidity validation state doesn't become stale when tokens change.

Applied to files:

  • src/apps/pulse/components/Sell/Sell.tsx
🧬 Code graph analysis (3)
src/apps/pulse/components/Buy/Buy.tsx (1)
src/services/tokensData.ts (1)
  • PortfolioToken (31-34)
src/apps/pulse/components/App/HomeScreen.tsx (1)
src/services/tokensData.ts (1)
  • PortfolioToken (31-34)
src/apps/pulse/components/Sell/Sell.tsx (3)
src/services/tokensData.ts (1)
  • PortfolioToken (31-34)
src/apps/pulse/utils/constants.ts (1)
  • getChainId (28-49)
src/apps/pulse/utils/blockchain.ts (3)
  • isNativeToken (17-18)
  • NativeSymbols (20-27)
  • ChainNames (29-36)
⏰ 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 (2)
src/apps/pulse/components/App/tests/AppWrapper.test.tsx (1)

59-62: LGTM! Test mock aligns with new data structure.

The mock data correctly reflects the updated API response shape (assets instead of tokens) and includes the new wallets and balances_length fields.

src/apps/pulse/components/Buy/tests/Buy.test.tsx (1)

167-190: LGTM! Comprehensive test coverage for portfolioTokens scenarios.

The test updates correctly supply the new portfolioTokens prop with appropriate mock data for different wallet states (normal balance, low balance, insufficient gas). The mock data structure aligns with the PortfolioToken type definition.

Also applies to: 545-568, 653-676

@vignesha22 vignesha22 merged commit 2ea4de6 into staging Oct 13, 2025
6 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Oct 14, 2025
3 tasks
@coderabbitai coderabbitai bot mentioned this pull request Dec 2, 2025
3 tasks
@coderabbitai coderabbitai bot mentioned this pull request Dec 23, 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