Conversation
WalkthroughAdds wrapped-native token detection utilities and uses them to filter out wrapped native tokens and adjust display name/symbol in parsing and portfolio conversion; one UI comment updated to mention wrapped native tokens. Changes
Sequence Diagram(s)sequenceDiagram
participant UI as PortfolioTokenList (UI)
participant Parse as parseSearchData
participant Service as pillarXApiWalletPortfolio
participant Chain as blockchain utils
Note over Chain: New utilities<br/>(isWrappedNativeToken, getWrappedTokenSymbol)
UI->>Chain: isWrappedNativeToken(addr, chainId)
alt wrapped
Chain-->>UI: true
UI-->>UI: exclude token from display
else not wrapped
Chain-->>UI: false
UI-->>UI: include token
end
Parse->>Chain: isWrappedNativeToken(contract, chainId)
alt wrapped
Chain-->>Parse: true
Parse->>Chain: getWrappedTokenSymbol(chainId)
Chain-->>Parse: symbol
Parse-->>App: exclude or label as wrapped
else not wrapped
Chain-->>Parse: false
Parse-->>App: include token entry
end
Service->>Chain: isWrappedNativeToken(contract, chainId)
alt wrapped
Chain-->>Service: true
Service->>Chain: getWrappedTokenSymbol(chainId)
Chain-->>Service: symbol
Service-->>App: token with "Wrapped <Name>" and wrapped symbol
else not wrapped
Chain-->>Service: false
Service-->>App: token unchanged
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
Deploying x with
|
| Latest commit: |
2177c74
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://6769696f.x-e62.pages.dev |
| Branch Preview URL: | https://pro-3864-wrappedtokenfilter.x-e62.pages.dev |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/utils/blockchain.ts (1)
523-525: Consider a more defensive fallback for unsupported chainIds.The function returns an empty string when a chainId is not found in the mapping. While this is unlikely to cause issues in practice (since
isWrappedNativeTokenwould also return false for unsupported chainIds), it could lead to display issues if the mappings get out of sync.Consider one of these alternatives:
export const getWrappedTokenSymbol = (chainId: number): string => { - return WRAPPED_NATIVE_TOKEN_SYMBOLS[chainId] || ''; + const symbol = WRAPPED_NATIVE_TOKEN_SYMBOLS[chainId]; + if (!symbol) { + console.warn(`No wrapped token symbol found for chainId: ${chainId}`); + return ''; + } + return symbol; };Or return undefined to make the absence explicit:
export const getWrappedTokenSymbol = (chainId: number): string | undefined => { return WRAPPED_NATIVE_TOKEN_SYMBOLS[chainId]; };src/apps/pulse/utils/parseSearchData.ts (1)
79-100: Consider extracting the wrapped token logic into a shared utility.The wrapped token detection and display name/symbol computation is duplicated across
parseAssetData,parseTokenData, andparseFreshAndTrendingTokens. While the current implementation is correct, consider extracting this into a reusable utility function to reduce duplication and improve maintainability.Example refactor:
function getTokenDisplayInfo( address: string, chainId: number, name: string, symbol: string ) { const isWrapped = isWrappedNativeToken(address, chainId); return { displayName: isWrapped ? `Wrapped ${name}` : name, displaySymbol: isWrapped ? getWrappedTokenSymbol(chainId) : symbol, }; }Then use it in the parsing functions:
const { displayName, displaySymbol } = getTokenDisplayInfo( contractAddress, chainId, asset.name, asset.symbol );
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/apps/pulse/components/Search/PortfolioTokenList.tsx(2 hunks)src/apps/pulse/utils/parseSearchData.ts(4 hunks)src/services/pillarXApiWalletPortfolio.ts(2 hunks)src/utils/blockchain.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-05-23T14:44:33.911Z
Learnt from: RanaBug
Repo: pillarwallet/x PR: 315
File: src/apps/the-exchange/utils/wrappedTokens.ts:6-20
Timestamp: 2025-05-23T14:44:33.911Z
Learning: XDAI (Gnosis Chain) is intentionally excluded from the WRAPPED_NATIVE_TOKEN_ADDRESSES mapping in the exchange app's wrappedTokens utility.
Applied to files:
src/utils/blockchain.tssrc/services/pillarXApiWalletPortfolio.ts
📚 Learning: 2025-03-28T09:22:22.712Z
Learnt from: RanaBug
Repo: pillarwallet/x PR: 275
File: src/apps/the-exchange/components/DropdownTokensList/DropdownTokenList.tsx:180-195
Timestamp: 2025-03-28T09:22:22.712Z
Learning: In the Exchange app, `swapTokenList` and `receiveTokenList` are derived from `searchTokenResult` when search is active, so including `searchToken` in the useEffect dependency array that uses these lists would be redundant as the lists will update when search results change.
Applied to files:
src/apps/pulse/components/Search/PortfolioTokenList.tsx
📚 Learning: 2025-04-23T15:04:20.826Z
Learnt from: RanaBug
Repo: pillarwallet/x PR: 290
File: src/apps/pillarx-app/components/TileTitle/TitleTitle.tsx:6-10
Timestamp: 2025-04-23T15:04:20.826Z
Learning: In this repository, TileTitleProps and TileTitle are different types that serve different purposes. TileTitleProps is used for the TileTitle component and has optional fields (title?, leftDecorator?, rightDecorator?), while TileTitle in api.ts has a required text field. The TileTitleProps interface aligns with the TokensMarketData.title type in api.ts which also has optional fields.
Applied to files:
src/apps/pulse/components/Search/PortfolioTokenList.tsx
📚 Learning: 2025-04-23T15:04:20.826Z
Learnt from: RanaBug
Repo: pillarwallet/x PR: 290
File: src/apps/pillarx-app/components/TileTitle/TitleTitle.tsx:6-10
Timestamp: 2025-04-23T15:04:20.826Z
Learning: In this repository, TileTitleProps and TileTitle are different types that serve different purposes. TileTitleProps is used for the TileTitle component and has optional fields (title?, leftDecorator?, rightDecorator?), while TileTitle in api.ts has a required title field. The TileTitleProps structure aligns with how it's used in the TokensMarketData type in api.ts.
Applied to files:
src/apps/pulse/components/Search/PortfolioTokenList.tsx
📚 Learning: 2025-11-04T14:34:00.373Z
Learnt from: RanaBug
Repo: pillarwallet/x PR: 445
File: src/containers/Authorized.tsx:63-77
Timestamp: 2025-11-04T14:34:00.373Z
Learning: In src/containers/Authorized.tsx, the tempKit useEffect intentionally excludes chainId from its dependency array because the kit is used by useWalletModeVerification to check wallet mode across all supported chains, regardless of the currently selected chainId. The chainId parameter is only used for initial kit configuration and does not affect the multi-chain verification results.
Applied to files:
src/apps/pulse/components/Search/PortfolioTokenList.tsxsrc/services/pillarXApiWalletPortfolio.ts
🧬 Code graph analysis (4)
src/utils/blockchain.ts (1)
src/apps/the-exchange/utils/wrappedTokens.ts (1)
WRAPPED_NATIVE_TOKEN_ADDRESSES(8-21)
src/apps/pulse/components/Search/PortfolioTokenList.tsx (3)
src/services/pillarXApiWalletPortfolio.ts (1)
convertPortfolioAPIResponseToToken(27-61)src/utils/blockchain.ts (1)
isWrappedNativeToken(514-521)src/services/tokensData.ts (1)
chainNameToChainIdTokensData(234-255)
src/services/pillarXApiWalletPortfolio.ts (2)
src/utils/blockchain.ts (2)
isWrappedNativeToken(514-521)getWrappedTokenSymbol(523-525)src/services/tokensData.ts (1)
chainIdToChainNameTokensData(210-231)
src/apps/pulse/utils/parseSearchData.ts (3)
src/services/tokensData.ts (1)
chainNameToChainIdTokensData(234-255)src/utils/blockchain.ts (3)
isWrappedNativeToken(514-521)getWrappedTokenSymbol(523-525)getChainName(269-288)src/types/api.ts (1)
TokensMarketData(170-177)
⏰ 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 (9)
src/apps/pulse/components/Search/PortfolioTokenList.tsx (2)
12-15: LGTM on the import addition.The import of
isWrappedNativeTokenis correctly placed and necessary for the filtering logic below.
58-65: Wrapped token filtering logic looks correct.The filter correctly excludes both stable currencies and wrapped native tokens. The usage of
chainNameToChainIdTokensDatato convert the blockchain name to a chainId for theisWrappedNativeTokencheck is consistent with the pattern used elsewhere in this PR.src/services/pillarXApiWalletPortfolio.ts (2)
17-22: LGTM on the import additions.The imports of
isWrappedNativeTokenandgetWrappedTokenSymbolare correctly placed and necessary for the wrapped token handling logic below.
35-59: Wrapped token handling logic looks correct.The implementation properly:
- Extracts the chainId from the contract's chainId string
- Detects wrapped native tokens
- Adjusts the display name to "Wrapped " format
- Uses the correct wrapped token symbol from
getWrappedTokenSymbolThe logic is consistent with the approach used in
parseSearchData.ts.src/utils/blockchain.ts (2)
514-521: LGTM on the wrapped token detection logic.The function correctly handles:
- Unsupported chainIds by returning false
- Case-insensitive address comparison (appropriate for Ethereum addresses)
496-503: No issues found—mappings are consistent and correct.Verification confirms that
WRAPPED_NATIVE_TOKEN_ADDRESSESinblockchain.tsmatches the exchange app exactly. Both include the same 6 chains (Ethereum, Polygon, Optimism, Arbitrum, Base, BNB) with identical addresses. XDAI (chainId 100) is intentionally excluded in both locations, as documented in the exchange app with the comment "// Not including XDAI below," and confirmed by the explicit XDAI filtering inblockchain.ts.src/apps/pulse/utils/parseSearchData.ts (3)
14-18: LGTM on the import additions.The imports are correctly placed and necessary for the wrapped token handling logic in the parsing functions below.
46-67: Wrapped token handling in parseAssetData looks correct.The implementation properly detects wrapped native tokens and adjusts the display name and symbol accordingly. The pattern is consistent with the approach used in
pillarXApiWalletPortfolio.ts.
128-159: Wrapped token handling in parseFreshAndTrendingTokens looks correct.The implementation properly handles wrapped native tokens by:
- Extracting the chainId from the projection id
- Detecting wrapped tokens
- Computing appropriate display names and symbols
The logic is consistent with the other parsing functions in this file.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/utils/blockchain.ts (2)
496-503: Consider consolidating duplicate wrapped token mappings.This mapping duplicates
WRAPPED_NATIVE_TOKEN_ADDRESSESfromsrc/apps/the-exchange/utils/wrappedTokens.ts(identical addresses for all chains). Additionally, the Polygon address on line 498 duplicates the existingWRAPPED_POL_TOKEN_ADDRESSconstant defined at lines 59-60 in this same file.Consider consolidating these into a single shared utility to reduce maintenance burden when addresses need updates.
If there's a deliberate architectural reason to keep exchange app utilities separate from general utilities, consider at least reusing
WRAPPED_POL_TOKEN_ADDRESSfor the Polygon entry:export const WRAPPED_NATIVE_TOKEN_ADDRESSES: Record<number, string> = { - 137: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270', // Polygon - WPOL + 137: WRAPPED_POL_TOKEN_ADDRESS, // Polygon - WPOL };
514-521: Implementation looks good with optional input validation.The case-insensitive address comparison is correct for Ethereum addresses, and the function properly handles unsupported chains.
Optionally, consider adding basic input validation to catch invalid inputs early:
export const isWrappedNativeToken = ( tokenAddress: string, chainId: number ): boolean => { + if (!tokenAddress || !chainId) return false; const wrappedAddress = WRAPPED_NATIVE_TOKEN_ADDRESSES[chainId]; if (!wrappedAddress) return false; return tokenAddress.toLowerCase() === wrappedAddress.toLowerCase(); };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/apps/pulse/utils/parseSearchData.ts(4 hunks)src/utils/blockchain.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/apps/pulse/utils/parseSearchData.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: RanaBug
Repo: pillarwallet/x PR: 315
File: src/apps/the-exchange/utils/wrappedTokens.ts:6-20
Timestamp: 2025-05-23T14:44:33.911Z
Learning: XDAI (Gnosis Chain) is intentionally excluded from the WRAPPED_NATIVE_TOKEN_ADDRESSES mapping in the exchange app's wrappedTokens utility.
📚 Learning: 2025-05-23T14:44:33.911Z
Learnt from: RanaBug
Repo: pillarwallet/x PR: 315
File: src/apps/the-exchange/utils/wrappedTokens.ts:6-20
Timestamp: 2025-05-23T14:44:33.911Z
Learning: XDAI (Gnosis Chain) is intentionally excluded from the WRAPPED_NATIVE_TOKEN_ADDRESSES mapping in the exchange app's wrappedTokens utility.
Applied to files:
src/utils/blockchain.ts
🧬 Code graph analysis (1)
src/utils/blockchain.ts (1)
src/apps/the-exchange/utils/wrappedTokens.ts (1)
WRAPPED_NATIVE_TOKEN_ADDRESSES(8-21)
⏰ 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 (2)
src/utils/blockchain.ts (2)
505-512: LGTM!The wrapped native token symbols mapping is correctly defined for all supported chains.
523-525: No action required—the code is safe.The mappings are perfectly aligned: both
WRAPPED_NATIVE_TOKEN_ADDRESSESandWRAPPED_NATIVE_TOKEN_SYMBOLScontain identical chain IDs (1, 137, 10, 42161, 8453, 56). SincegetWrappedTokenSymbolis only called whenisWrappedNativeTokenreturns true, and that function checksWRAPPED_NATIVE_TOKEN_ADDRESSES[chainId]exists before returning true, the chainId is guaranteed to exist in both mappings. The empty string fallback is defensive programming and unreachable in practice.
Description
How Has This Been Tested?
Screenshots (if appropriate):
Types of changes
Summary by CodeRabbit