Skip to content

Conversation

@NeOMakinG
Copy link
Collaborator

@NeOMakinG NeOMakinG commented Nov 27, 2025

Description

9000 birds one stone:

  • Consume feat: support tron with native wallet hdwallet#750 to be able to use tron with our native wallet
  • Adds the TRON chain support
  • Account discovery
  • I added a tron api adapter on top of our TronChainAdapter so we can talk like unchained but using the public RPC
  • Relay compatibility (It supports USDT on Tron only)
  • Near compatibility (It supports TRX on Tron only)
  • Support sending TR20 and TRX on tron chain
  • Balances update (we are using getaccount from the public RPC to get all the TRC20 balances and native balances
  • Add TRON tokens to coingecko
  • Add tron tokens prices

Some noticable things:

  • TX History isn't supported (and isn't implemented) but could if we use an API key for the RPC which will then allow us to query TXs, some questions might remains about that like are we able to index things properly on the front end side
  • I had to refetch getAccount for the said accounts for the send and swaps when one of the actions are resolved, because we don't have a websocket pushing incoming TXs like we do for unchained
  • I had to add a throttle to the Tron API because its limited to 1 request by second so account discovery could take minimum 10 sec for 10 accounts

Issue (if applicable)

We dont have an issue for that and fck off we need to get things done

Risk

Medium as it's behind a flag?

High Risk PRs Require 2 approvals

What protocols, transaction types, wallets or contract interactions might be affected by this PR?

Testing

  • Using native wallet with feat: support tron with native wallet hdwallet#750 use the workflow to publish on verdaccio
  • You are able to see you TRON accounts and fetch new accounts
  • You should be able to see your balances for your TRC20 and native tokens on TRON
  • Sending on TRON should work (both using native assets and TRC20)
  • Swapping to any chains supported by relay to USDT on Tron should work and the contrary
  • Swapping to any chains supported by near intents to TRX or from TRX should work as expected, it also supports USDT
  • Balances should be updated after sending/swapping

Note: Sending to a second account might not update the second account but considering the amount of work there I was seeing that as a stretch and could be done as a follow up, we could have the notion of toAccountId in the send action to be able to resolve that
2nd note: Sending might fail because out of energy (gas), we will probably want to take care of that in a near future but also feels like a small stretch for me right now considering the size of the PR

Engineering

Operations

  • 🏁 My feature is behind a flag and doesn't require operations testing (yet)

Screenshots (if applicable)

Swaps: https://jam.dev/c/2972d1ed-95ff-4d14-8dbf-89927a1230a1
image
image
image

Summary by CodeRabbit

  • New Features
    • Added Tron (TRX) network support for trading, sending, and receiving.
    • Enabled TRC20 token support, fee estimation, and unsigned/signed transaction flows.
    • Integrated Tron wallet/address management and balance/token display.
    • Exposed Tron transaction fee APIs and transaction building for swaps/relays.
    • Tron support gated by a feature flag and configurable node URL.

✏️ Tip: You can customize this high-level summary in your review settings.

@NeOMakinG NeOMakinG requested a review from a team as a code owner November 27, 2025 15:48
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 27, 2025

📝 Walkthrough

Walkthrough

Adds end-to-end Tron (TRX) support: env flags, CSP, CAIP constants, chain adapter, unchained client, parsers, swapper integrations, UI/hooks, asset generation, types, and supporting utilities across the codebase.

Changes

Cohort / File(s) Change Summary
Environment & Config
\.env, \.env.development, src/config.ts, src/vite-env.d.ts
Added VITE_TRON_NODE_URL and VITE_FEATURE_TRON feature flag and validators; default feature flag false in mocks.
CSP / Headers
headers/csps/chains/tron.ts, headers/csps/index.ts
New CSP module for Tron; included in exported CSP list (connect-src → VITE_TRON_NODE_URL).
Dependencies
package.json
Added tronweb@6.1.0 and bumped multiple @shapeshiftoss/hdwallet-* packages from alpha → stable.
CAIP Constants & Types
packages/caip/src/constants.ts, packages/types/src/base.ts
Added tronChainId, tronAssetId, CHAIN_NAMESPACE.Tron, CHAIN_REFERENCE.TronMainnet, ASSET_NAMESPACE.trc20, ASSET_REFERENCE.Tron, and TronChainId alias.
CAIP Adapters / Coingecko
packages/caip/src/adapters/coingecko/index.ts, packages/caip/src/adapters/coingecko/utils.ts, tests
Added Coingecko platform Tron, mapping logic, token handling and tests for Tron assets.
Chain Adapter (Tron)
packages/chain-adapters/src/tron/*, packages/chain-adapters/src/types.ts, packages/chain-adapters/src/index.ts
New Tron ChainAdapter, types, exports: address derivation, account/balance/token extraction, build/sign/broadcast, fee data, tx parsing.
Unchained Client (Tron)
packages/unchained-client/src/tron/*, packages/unchained-client/src/index.ts
New TronApi, parser, types, and re-exports: RPC calls, TRC10/TRC20 handling, tx history, fee estimation, sendTx/broadcast.
Swapper Core Types & Utils
packages/swapper/src/types.ts, packages/swapper/src/utils.ts
Added Tron-specific swapper types, execution inputs, executeTronTransaction util, and SwapperApi methods for unsigned Tron txs and fee retrieval.
Swapper Integrations (NearIntents / Relay / ButterSwap)
packages/swapper/src/swappers/NearIntentsSwapper/*, packages/swapper/src/swappers/RelaySwapper/*, packages/swapper/src/swappers/ButterSwap/*
Exposed getUnsignedTronTransaction & getTronTransactionFees, added Tron to supported chain lists, fee handling, trade validation, relay mappings, and test mocks.
Swapper Tron Utilities
packages/swapper/src/tron-utils/*, packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
New getUnsignedTronTransaction and getTronTransactionFees; explicit unsupported path for Tron in THORChain L1 flow.
Asset Data & Generation
packages/utils/src/assetData/*, scripts/generateAssetData/tron/*, scripts/generateAssetData/*
Added TRX base asset, base asset lookup, Coingecko TRC20 support, TrustWallet icon checks, and integrated Tron assets into generation pipeline.
Utilities & Mapping
packages/utils/src/*, src/lib/*, src/lib/utils/tron.ts
Added TRC20 token detection, fee asset mapping, chain short name, URN mapping, assertGetTronChainAdapter, and getTronTransactionStatus.
Account Derivation & State
src/lib/account/*, src/state/*, src/hooks/*
Added Tron account derivation, portfolio upserts, feature flag wiring, second-class chain polling for actions, and portfolio refreshes for Tron accounts.
UI / Send / Trade Execution
src/components/Modals/Send/utils.ts, src/components/MultiHopTrade/*, src/pages/RFOX/*
Integrated Tron fee estimation, build/send flows, trade execution path including sign & broadcast callbacks, and trade quote input handling.
Plugins & Activation
src/plugins/tron/index.tsx, src/plugins/activePlugins.ts, src/constants/chains.ts
New Tron plugin registering a tron chain adapter (gated by feature flag); added SECOND_CLASS_CHAINS including TronMainnet.
Headers / Types / Tests
src/vite-env.d.ts, various tests
Feature flag typing added; tests updated to include Tron assets/mocks.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI as Frontend UI
    participant Swapper as SwapperApi
    participant Adapter as TronChainAdapter
    participant Unchained as UnchainedClient
    participant Wallet

    User->>UI: Request trade quote (Tron)
    UI->>Swapper: getTradeQuote(chainId=Tron,...)
    Swapper->>Adapter: getFeeData()
    Adapter->>Unchained: estimateFees()/getPriorityFees()
    Unchained-->>Adapter: fee data
    Adapter-->>Swapper: FeeData
    Swapper-->>UI: TradeQuote

    User->>UI: Confirm trade
    UI->>Swapper: getUnsignedTronTransaction(tradeQuote)
    Swapper->>Adapter: buildSendApiTransaction(to, value, contract)
    Adapter->>Unchained: getTRC20Balance/txParams (if needed)
    Unchained-->>Adapter: chain data / unsigned tx
    Adapter-->>Swapper: TronUnsignedTx
    UI->>Wallet: sign TronUnsignedTx
    Wallet-->>UI: signed TronSignTx
    UI->>Swapper: executeTronTransaction(signedTx)
    Swapper->>Adapter: broadcastTransaction(signedTx)
    Adapter->>Unchained: sendTx(signedHex)
    Unchained-->>Adapter: txid
    Adapter-->>Swapper: txid
    Swapper-->>UI: execution result (txid)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60–90 minutes

Areas needing attention:

  • packages/chain-adapters/src/tron/TronChainAdapter.ts — derivation paths, TRC10 vs TRC20 handling, raw tx structure, signing/broadcast correctness.
  • packages/unchained-client/src/tron/api.ts and parser — RPC shape assumptions, throttling, error handling, and normalization.
  • Cross-package type integrations (packages/swapper/src/types.ts, packages/chain-adapters/src/types.ts) — ensure type consistency and export surface.
  • State/hooks polling and cleanup (useSendActionSubscriber/useSwapActionSubscriber) — interval refs, unmount cleanup, and race conditions.
  • Asset-generation scripts and TrustWallet URL checks — network requests and batching logic.

Possibly related PRs

Suggested labels

high risk

Suggested reviewers

  • NeOMakinG

Poem

🐰 I hopped through code with tiny paws so spry,
Added Tron rails so TRX may fly.
From adapters to parsers, nodes and fees,
Carrots of tokens dance in the breeze.
A little rabbit cheers — build, test, deploy with glee!

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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: support tron' directly and clearly describes the main objective of the PR, which is to add TRON blockchain support across the codebase.
✨ 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 tron-support

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.

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: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/state/slices/portfolioSlice/utils/index.ts (1)

360-364: Missing Tron case in isAssetSupportedByWallet - confirmed.

The function in src/state/slices/portfolioSlice/utils/index.ts (lines 324-363) does not include a case for tronChainId, even though tronChainId is imported at line 28. This causes Tron assets to incorrectly return false in the UI components that use this function to determine asset support:

  • src/pages/Explore/components/PortalAssetRow.tsx:53
  • src/components/AssetSelection/components/AssetChainDropdown/AssetChainDropdown.tsx:104
  • src/components/AssetSearch/components/AssetRow.tsx:104

A supportsTron function exists in @shapeshiftoss/hdwallet-core (as seen in src/hooks/useWalletSupportsChain/useWalletSupportsChain.ts:168), and the pattern is already correctly implemented in the similar useWalletSupportsChain hook.

Add the missing case: case tronChainId: return supportsTron(wallet) to the switch statement.

🧹 Nitpick comments (13)
src/components/Modals/Send/utils.ts (2)

128-136: Consider using assertGetTronChainAdapter for consistency.

For type safety and consistency with other chain implementations (EVM, Solana, CosmosSdk, UTXO), consider using assertGetTronChainAdapter instead of the generic assertGetChainAdapter. This would provide better type inference and follow the established pattern.

+import { assertGetTronChainAdapter } from '@/lib/utils/tron'

Then apply this change:

     case CHAIN_NAMESPACE.Tron: {
-      const adapter = assertGetChainAdapter(asset.chainId)
+      const adapter = assertGetTronChainAdapter(asset.chainId)
       const getFeeDataInput: GetFeeDataInput<KnownChainIds.TronMainnet> = {
         to,
         value,
         sendMax,
       }
       return adapter.getFeeData(getFeeDataInput)
     }

306-320: Consider using assertGetTronChainAdapter to avoid type assertion.

Using assertGetTronChainAdapter instead of the generic assertGetChainAdapter would eliminate the need for the type assertion on line 319 and provide better type safety, consistent with how other chains are handled in this file.

Apply this change:

     if (fromChainId(asset.chainId).chainNamespace === CHAIN_NAMESPACE.Tron) {
       const { accountNumber } = bip44Params
-      const adapter = assertGetChainAdapter(chainId)
+      const adapter = assertGetTronChainAdapter(chainId)
       const contractAddress = contractAddressOrUndefined(asset.assetId)
       return adapter.buildSendTransaction({
         to,
         value,
         wallet,
         accountNumber,
         sendMax: sendInput.sendMax,
         chainSpecific: {
           contractAddress,
         },
-      } as BuildSendTxInput<KnownChainIds.TronMainnet>)
+      })
     }
packages/unchained-client/src/tron/api.ts (4)

96-105: Log TRC20 balance fetch failures.

The catch block returns a default value without logging the error, making debugging difficult.

Apply this diff to add error logging:

     } catch (_err) {
+      console.error('Failed to fetch TRC20 balance:', _err)
       return '0'
     }

187-200: Log chain price fetch failures.

Silent fallback to default values makes it difficult to diagnose network or RPC issues.

Apply this diff:

     } catch (_err) {
+      console.error('Failed to fetch chain prices, using defaults:', _err)
       return { bandwidthPrice: 1000, energyPrice: 420 }
     }

216-244: Add error logging for TRC20 transfer fee estimation failures.

Returning a hardcoded fallback without logging makes it unclear when and why fee estimation failed.

Apply this diff:

     } catch (_err) {
+      console.error('Failed to estimate TRC20 transfer fee, using default:', _err)
       return '31000000'
     }

23-31: Consider documenting the throttle mechanism.

The throttling implementation enforces a 1.5-second minimum interval between requests. While the implementation is correct, the rationale (public RPC rate limits mentioned in PR objectives) would be valuable context for future maintainers.

Consider adding a brief inline note above the throttle method explaining why throttling is necessary (e.g., "Throttle requests to comply with public RPC rate limits").

.env.development (1)

89-89: Consider alphabetical ordering for consistency.

The static analysis tool suggests placing VITE_FEATURE_TRON before VITE_FEATURE_WC_DIRECT_CONNECTION to maintain alphabetical ordering of feature flags.

Apply this diff to maintain alphabetical ordering:

-VITE_FEATURE_WC_DIRECT_CONNECTION=true
 VITE_FEATURE_TRON=true
+VITE_FEATURE_WC_DIRECT_CONNECTION=true
src/state/slices/preferencesSlice/preferencesSlice.ts (1)

21-32: Ensure Tron feature flag is covered by migrations and test mocks

The new Tron flag and its initialization via getConfig().VITE_FEATURE_TRON are consistent with existing chain flags. Since preferences state is persisted, please double‑check that:

  • A corresponding migration was added under src/state/migrations/ so older persisted featureFlags objects get a defined Tron property.
  • src/test/mocks/store.ts (and any other store mocks) were updated to include the new Tron flag.

This keeps persisted state and tests in sync with the extended FeatureFlags shape. As per coding guidelines and learnings, migrations are required when changing persisted state structure.

Also applies to: 153-165

src/constants/chains.ts (1)

8-9: Verify SECOND_CLASS_CHAINS behavior with the Tron feature flag

SECOND_CLASS_CHAINS now always contains KnownChainIds.TronMainnet, independent of preferences.featureFlags.Tron. Depending on how this constant is used, Tron may still appear in “second‑class” chain lists even when the Tron feature flag is off.

Please confirm that:

  • Either downstream consumers of SECOND_CLASS_CHAINS also respect the Tron flag, or
  • This behavior (showing Tron there even when flagged off) is explicitly intended.

If it should be fully gated, you may want to align its usage with the Tron feature flag similarly to how knownChainIds integrates other chain flags.

scripts/generateAssetData/tron/index.ts (1)

12-42: TRON asset generation flow looks good; optional micro-optimization

The Coingecko fetch, de-duplication, batching, and allSettled icon enrichment pattern is solid and resilient to per-asset failures. If you ever touch this again, you could avoid calling generateTrustWalletUrl twice per asset by caching its result inside the batch loop, but this is purely optional for an offline script.

packages/unchained-client/src/tron/parser/index.ts (1)

13-16: Consider using readonly modifiers for immutable properties.

These properties are set once in the constructor and never mutated. Marking them readonly would improve type safety.

 export class TransactionParser {
-  assetId: AssetId
-  chainId: ChainId
-  assetReference: string
+  readonly assetId: AssetId
+  readonly chainId: ChainId
+  readonly assetReference: string
packages/chain-adapters/src/tron/TronChainAdapter.ts (2)

375-389: Address validation lacks checksum verification.

The current validation only checks prefix and length but doesn't verify the Base58Check encoding/checksum. While basic, this could allow some malformed addresses through.

Consider using TronWeb's isAddress utility for robust validation:

-  validateAddress(address: string): Promise<ValidAddressResult> {
-    try {
-      if (!address.startsWith('T')) {
-        return Promise.resolve({ valid: false, result: ValidAddressResultType.Invalid })
-      }
-
-      if (address.length !== 34) {
-        return Promise.resolve({ valid: false, result: ValidAddressResultType.Invalid })
-      }
-
-      return Promise.resolve({ valid: true, result: ValidAddressResultType.Valid })
-    } catch (err) {
-      return Promise.resolve({ valid: false, result: ValidAddressResultType.Invalid })
-    }
-  }
+  validateAddress(address: string): Promise<ValidAddressResult> {
+    const isValid = TronWeb.isAddress(address)
+    return Promise.resolve({
+      valid: isValid,
+      result: isValid ? ValidAddressResultType.Valid : ValidAddressResultType.Invalid,
+    })
+  }

196-200: TRC20 feeLimit is hardcoded to 100 TRX.

The feeLimit of 100,000,000 sun (100 TRX) is hardcoded. While this is a reasonable default, it may be excessive for simple transfers and could be insufficient for complex contract interactions.

Consider making this configurable via chainSpecific input or deriving it from fee estimation.

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 (2)
packages/unchained-client/src/tron/api.ts (2)

85-87: Log TRC20 token fetch failures for debugging.

The catch block silently swallows errors when fetching TRC20 tokens. While the graceful fallback is appropriate, logging would aid debugging in production.

Apply this diff:

-    } catch (_err) {
+    } catch (err) {
       // TRC20 fetch failed, continue with just TRC10 tokens
+      console.error('Failed to fetch TRC20 tokens:', err)
     }

As per coding guidelines: Log errors appropriately for debugging.


202-214: Preserve original error context in fee estimation.

The catch block throws a generic error, discarding the original error details that would be valuable for debugging fee estimation failures.

Apply this diff:

-    } catch (_err) {
-      throw new Error('Failed to estimate fees')
+    } catch (err) {
+      throw new Error(`Failed to estimate fees: ${err}`)
     }

As per coding guidelines: Provide meaningful error messages and log errors with relevant context.

🧹 Nitpick comments (4)
packages/unchained-client/src/tron/api.ts (4)

96-105: Consider logging TRC20 balance fetch errors.

Similar to other methods in this class, the catch block silently returns a default value. While the fallback is reasonable, logging would help diagnose contract interaction issues.

Apply this diff:

-    } catch (_err) {
+    } catch (err) {
+      console.error('Failed to fetch TRC20 balance:', { address: params.address, contractAddress: params.contractAddress, error: err })
       return '0'
     }

187-200: Consider logging chain price fetch errors.

Consistent with other methods, this silent catch makes debugging difficult if chain parameter queries fail. The defaults are reasonable but logging would help identify RPC issues.

Apply this diff:

-    } catch (_err) {
+    } catch (err) {
+      console.error('Failed to fetch chain prices, using defaults:', err)
       return { bandwidthPrice: 1000, energyPrice: 420 }
     }

216-244: Consider logging TRC20 transfer fee estimation errors.

Consistent with the pattern throughout this class, the silent catch makes it difficult to diagnose why fee estimation might fail (e.g., invalid contract, RPC issues).

Apply this diff:

-    } catch (_err) {
+    } catch (err) {
+      console.error('Failed to estimate TRC20 transfer fee, using default:', { params, error: err })
       return '31000000'
     }

246-275: Consider logging priority fee estimation errors.

The silent catch follows the pattern used throughout this class. While the fallback values are reasonable, logging would help identify chain parameter query issues.

Apply this diff:

-    } catch (_err) {
+    } catch (err) {
+      console.error('Failed to fetch priority fees, using defaults:', err)
       const defaultFee = '268000'
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a1d9dd9 and 7bb446a.

📒 Files selected for processing (1)
  • packages/unchained-client/src/tron/api.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Never assume a library is available - always check imports/package.json first
Prefer composition over inheritance
Write self-documenting code with clear variable and function names
Keep functions small and focused on a single responsibility
Avoid deep nesting - use early returns instead
Prefer procedural and easy to understand code
Never expose, log, or commit secrets, API keys, or credentials
Validate all inputs, especially user inputs
Handle errors gracefully with meaningful messages
Don't silently catch and ignore exceptions
Log errors appropriately for debugging
Provide fallback behavior when possible
Use appropriate data structures for the task
Never add code comments unless explicitly requested
When modifying code, do not add comments that reference previous implementations or explain what changed. Comments should only describe the current logic and functionality.
Use meaningful names for branches, variables, and functions
Always run yarn lint --fix and yarn type-check after making changes
Avoid let variable assignments - prefer const with inline IIFE switch statements or extract to functions for conditional logic

Files:

  • packages/unchained-client/src/tron/api.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Avoid useEffect where practical - use it only when necessary and following best practices
Avoid 'any' types - use specific type annotations instead
For default values with user overrides, use computed values (useMemo) instead of useEffect - pattern: userSelected ?? smartDefault ?? fallback
When function parameters are unused due to interface requirements, refactor the interface or implementation to remove them rather than prefixing with underscore
Sanitize data before displaying to prevent XSS
Memoize aggressively - wrap component variables in useMemo and callbacks in useCallback where possible
For static JSX icon elements (e.g., <TbCopy />) that don't depend on state/props, define them as constants outside the component to avoid re-renders instead of using useMemo
Account for light/dark mode using useColorModeValue hook
Account for responsive mobile designs in all UI components
When applying styles, use the existing standards and conventions of the codebase
Use Chakra UI components and conventions
All copy/text must use translation keys - never hardcode strings
Use the translation hook: useTranslate() from react-polyglot
Use useFeatureFlag('FlagName') hook to access feature flag values in components
Prefer type over interface for type definitions
Use strict typing - avoid any
Use Nominal types for domain identifiers (e.g., WalletId, AccountId)
Import types from @shapeshiftoss/caip for chain/account/asset IDs
Use useAppSelector for Redux state
Use useAppDispatch for Redux actions
Memoize expensive computations with useMemo
Memoize callbacks with useCallback

**/*.{ts,tsx}: Use Result<T, E> pattern for error handling in swappers and APIs; ALWAYS use Ok() and Err() from @sniptt/monads; AVOID throwing within swapper API implementations
ALWAYS use custom error classes from @shapeshiftoss/errors with meaningful error codes for internationalization and relevant details in error objects
ALWAYS wrap async op...

Files:

  • packages/unchained-client/src/tron/api.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Use camelCase for variables, functions, and methods with descriptive names that explain the purpose
Use verb prefixes for functions that perform actions (e.g., fetch, validate, execute, update, calculate)
Use UPPER_SNAKE_CASE for constants and configuration values with descriptive names
Use handle prefix for event handlers with descriptive names in camelCase
Use descriptive boolean variable names with is, has, can, should prefixes
Use named exports for components, functions, and utilities instead of default exports
Use descriptive import names and avoid renaming imports unless necessary
Avoid non-descriptive variable names like data, item, obj, and single-letter variable names except in loops
Avoid abbreviations in names unless they are widely understood
Avoid generic function names like fn, func, or callback

Files:

  • packages/unchained-client/src/tron/api.ts
🧠 Learnings (24)
📓 Common learnings
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/RFOX/components/Stake/components/StakeSummary.tsx:112-114
Timestamp: 2025-08-22T13:00:44.879Z
Learning: NeOMakinG prefers to keep PR changes minimal and focused on the core objectives, avoiding cosmetic or defensive code improvements that aren't directly related to the PR scope, even when they would improve robustness.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10128
File: .cursor/rules/error-handling.mdc:266-274
Timestamp: 2025-07-29T10:35:22.059Z
Learning: NeOMakinG prefers less nitpicky suggestions on documentation and best practices files, finding overly detailed suggestions on minor implementation details (like console.error vs logger.error) too granular for cursor rules documentation.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/pages/Dashboard/components/AccountList/AccountTable.tsx:60-0
Timestamp: 2025-09-02T08:34:08.157Z
Learning: NeOMakinG prefers code review comments to focus only on actual PR changes, not pre-existing code issues, unless there are critical security or correctness concerns directly related to the new functionality.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10234
File: src/components/MultiHopTrade/hooks/useGetTradeQuotes/hooks/useTrackTradeQuotes.ts:42-86
Timestamp: 2025-08-08T11:41:22.794Z
Learning: NeOMakinG prefers not to include refactors in move-only PRs; such suggestions should be deferred to follow-up issues instead of being applied within the same PR.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/components/Table/Table.theme.ts:177-180
Timestamp: 2025-09-02T12:38:46.940Z
Learning: NeOMakinG prefers to defer technical debt and CSS correctness issues (like improper hover selectors) to follow-up PRs when the current PR is already large and focused on major feature implementation, even when the issues are valid from a usability/technical perspective.
📚 Learning: 2025-11-24T21:20:44.637Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:20:44.637Z
Learning: Applies to **/*.tsx : Ensure TypeScript types are explicit and proper; avoid use of `any` type

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Avoid 'any' types - use specific type annotations instead

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Use strict typing - avoid `any`

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : NEVER use `any` type unless absolutely necessary in TypeScript

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use `unknown` instead of `any` when type is truly unknown in TypeScript

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use explicit types for function parameters and return values in TypeScript

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/**/*.ts : Use TypeScript with explicit types (e.g., SupportedChainIds) for all code in the Swapper system

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use explicit types for object shapes using interfaces or type aliases in TypeScript

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use type guards instead of type assertions when possible in TypeScript

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use descriptive property names in TypeScript type definitions

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Log errors appropriately for debugging

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:17.804Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-11-24T21:20:17.804Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS log errors for debugging using structured logging with relevant context and error metadata

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Don't silently catch and ignore exceptions

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-12T10:35:51.632Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:33-45
Timestamp: 2025-09-12T10:35:51.632Z
Learning: gomesalexandre consistently dismisses CodeRabbit suggestions about replacing console.error/console.warn with structured logging in API integration code, preferring simple console logging for debugging Tenderly transaction simulation APIs in WalletConnect flows.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Handle errors gracefully with meaningful messages

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-10-01T07:42:40.195Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10596
File: src/components/Layout/Header/NavBar/WalletConnectedMenu.tsx:77-99
Timestamp: 2025-10-01T07:42:40.195Z
Learning: In WalletConnectedMenu.tsx's handleReconnectWallet handler, gomesalexandre prefers throwing an error for unsupported wallet types in the default case rather than gracefully handling with a fallback. His reasoning: "if we have a problem here, we have bigger problems" - only supported wallets (KeepKey, Ledger, MetaMask, Coinbase, Phantom) should reach the reconnect flow when disconnected/locked, so encountering an unsupported type indicates a larger architectural issue that should be surfaced explicitly rather than masked with graceful degradation.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:17.804Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-11-24T21:20:17.804Z
Learning: Applies to **/swapper{s,}/**/*.{ts,tsx} : ALWAYS use `makeSwapErrorRight` for swapper errors with `TradeQuoteError` enum for error codes and provide detailed error information

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:17.804Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-11-24T21:20:17.804Z
Learning: Applies to **/*.{tsx,jsx} : ALWAYS wrap React components in error boundaries and provide user-friendly fallback components with error logging

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/**/*.ts : Validate inputs and log errors for debugging in Swapper system implementations

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:17.804Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-11-24T21:20:17.804Z
Learning: Applies to **/*.{tsx,jsx} : ALWAYS use `useErrorToast` hook for displaying errors with translated error messages and handle different error types appropriately

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-12T10:44:46.723Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/content/SendTransactionContent.tsx:0-0
Timestamp: 2025-09-12T10:44:46.723Z
Learning: gomesalexandre dismissed a clipboard error handling suggestion in PR #10461 for SendTransactionContent.tsx, demonstrating that the current navigator.clipboard.writeText implementation works as expected and preferring to keep it simple without additional try/catch error handling.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:17.804Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-11-24T21:20:17.804Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use custom error classes from `shapeshiftoss/errors` with meaningful error codes for internationalization and relevant details in error objects

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:44.637Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:20:44.637Z
Learning: Applies to **/*.{jsx,tsx} : ALWAYS provide user-friendly error messages in error handling

Applied to files:

  • packages/unchained-client/src/tron/api.ts
⏰ 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). (1)
  • GitHub Check: Install and Cache
🔇 Additional comments (4)
packages/unchained-client/src/tron/api.ts (4)

11-11: Past typing issue has been addressed.

The tronWeb property is now properly typed as TronWeb | null instead of any, which resolves the previous review concern about TypeScript best practices.


23-38: LGTM!

The throttling mechanism and lazy TronWeb initialization are well-implemented. The throttle pattern using a promise queue effectively enforces the 1.5-second minimum interval between requests.


107-112: LGTM!

Explicitly throwing for unsupported transaction history is appropriate and aligns with the PR's documented limitations (history requires an RPC API key).


161-185: LGTM!

The sendTx method has good error handling, providing meaningful error messages and preserving original error context when broadcasting fails. The validation of the result and txid before returning is appropriate.

Copy link
Contributor

@gomesalexandre gomesalexandre left a comment

Choose a reason for hiding this comment

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

Certified gangster 🥇

See hdwallet review (tested w this PR and verdaccio):

shapeshift/hdwallet#750 (review)

Additional bits:

  • Can add to markets page as follow-up to ease discovery while testing if we want
Image
  • TRC20 page is happy ✅ (although missing related assets)
Image
  • Swap to TRC20 is happy with Relay, with completion detection and balance update ✅
Image
  • Explorer Tx links are happy ✅

  • TRC20 -> TRX swap with completion detection and balance update ✅

Image Image

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

🧹 Nitpick comments (1)
.env (1)

229-229: Move feature flag to the feature flags section at the top.

The VITE_FEATURE_TRON flag is currently placed at the very end of the file, but should be grouped with other VITE_FEATURE_* flags in the feature flags section (lines 4–58) for consistency and maintainability.

Move the flag from line 229 to the feature flags section (consider placing it after VITE_FEATURE_NEAR_INTENTS_SWAP=true on line 38 for logical grouping near other swap-related features, or after VITE_FEATURE_SOLANA=true on line 9 for chain-related grouping):

 VITE_FEATURE_NEAR_INTENTS_SWAP=true
+VITE_FEATURE_TRON=false
 VITE_FEATURE_RUNEPOOL=true

Then remove the duplicate from the end of the file:

 VITE_NOTIFICATIONS_SERVER_URL=https://shapeshiftnotifications-service-production.up.railway.app

-VITE_FEATURE_TRON=false
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 14aaa6d and 0af9799.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (7)
  • .env (1 hunks)
  • .env.development (2 hunks)
  • package.json (2 hunks)
  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts (2 hunks)
  • packages/swapper/src/types.ts (12 hunks)
  • src/hooks/useActionCenterSubscribers/useSwapActionSubscriber.tsx (4 hunks)
  • src/lib/tradeExecution.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/hooks/useActionCenterSubscribers/useSwapActionSubscriber.tsx
  • src/lib/tradeExecution.ts
  • package.json
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Never assume a library is available - always check imports/package.json first
Prefer composition over inheritance
Write self-documenting code with clear variable and function names
Keep functions small and focused on a single responsibility
Avoid deep nesting - use early returns instead
Prefer procedural and easy to understand code
Never expose, log, or commit secrets, API keys, or credentials
Validate all inputs, especially user inputs
Handle errors gracefully with meaningful messages
Don't silently catch and ignore exceptions
Log errors appropriately for debugging
Provide fallback behavior when possible
Use appropriate data structures for the task
Never add code comments unless explicitly requested
When modifying code, do not add comments that reference previous implementations or explain what changed. Comments should only describe the current logic and functionality.
Use meaningful names for branches, variables, and functions
Always run yarn lint --fix and yarn type-check after making changes
Avoid let variable assignments - prefer const with inline IIFE switch statements or extract to functions for conditional logic

Files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
  • packages/swapper/src/types.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Avoid useEffect where practical - use it only when necessary and following best practices
Avoid 'any' types - use specific type annotations instead
For default values with user overrides, use computed values (useMemo) instead of useEffect - pattern: userSelected ?? smartDefault ?? fallback
When function parameters are unused due to interface requirements, refactor the interface or implementation to remove them rather than prefixing with underscore
Sanitize data before displaying to prevent XSS
Memoize aggressively - wrap component variables in useMemo and callbacks in useCallback where possible
For static JSX icon elements (e.g., <TbCopy />) that don't depend on state/props, define them as constants outside the component to avoid re-renders instead of using useMemo
Account for light/dark mode using useColorModeValue hook
Account for responsive mobile designs in all UI components
When applying styles, use the existing standards and conventions of the codebase
Use Chakra UI components and conventions
All copy/text must use translation keys - never hardcode strings
Use the translation hook: useTranslate() from react-polyglot
Use useFeatureFlag('FlagName') hook to access feature flag values in components
Prefer type over interface for type definitions
Use strict typing - avoid any
Use Nominal types for domain identifiers (e.g., WalletId, AccountId)
Import types from @shapeshiftoss/caip for chain/account/asset IDs
Use useAppSelector for Redux state
Use useAppDispatch for Redux actions
Memoize expensive computations with useMemo
Memoize callbacks with useCallback

**/*.{ts,tsx}: Use Result<T, E> pattern for error handling in swappers and APIs; ALWAYS use Ok() and Err() from @sniptt/monads; AVOID throwing within swapper API implementations
ALWAYS use custom error classes from @shapeshiftoss/errors with meaningful error codes for internationalization and relevant details in error objects
ALWAYS wrap async op...

Files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
  • packages/swapper/src/types.ts
**/swapper{s,}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

ALWAYS use makeSwapErrorRight for swapper errors with TradeQuoteError enum for error codes and provide detailed error information

Files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
  • packages/swapper/src/types.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Use camelCase for variables, functions, and methods with descriptive names that explain the purpose
Use verb prefixes for functions that perform actions (e.g., fetch, validate, execute, update, calculate)
Use UPPER_SNAKE_CASE for constants and configuration values with descriptive names
Use handle prefix for event handlers with descriptive names in camelCase
Use descriptive boolean variable names with is, has, can, should prefixes
Use named exports for components, functions, and utilities instead of default exports
Use descriptive import names and avoid renaming imports unless necessary
Avoid non-descriptive variable names like data, item, obj, and single-letter variable names except in loops
Avoid abbreviations in names unless they are widely understood
Avoid generic function names like fn, func, or callback

Files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
  • packages/swapper/src/types.ts
packages/swapper/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/swapper.mdc)

packages/swapper/**/*.ts: Use TypeScript with explicit types (e.g., SupportedChainIds) for all code in the Swapper system
Use camelCase for variable and function names in the Swapper system
Use PascalCase for types, interfaces, and enums in the Swapper system
Use kebab-case for filenames in the Swapper system

Files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
  • packages/swapper/src/types.ts
packages/swapper/src/swappers/**/*.ts

📄 CodeRabbit inference engine (.cursor/rules/swapper.mdc)

packages/swapper/src/swappers/**/*.ts: Adhere to the Swapper directory structure: each swapper resides in packages/swapper/src/swappers// with required files (SwapperName.ts, endpoints.ts, types.ts, utils/constants.ts, utils/helpers.ts)
Validate inputs and log errors for debugging in Swapper system implementations
Swapper files must be located in packages/swapper/src/swappers/ directory structure and not placed outside this location
Avoid side effects in swap logic; ensure swap methods are deterministic and stateless

Files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
packages/swapper/src/swappers/*/*.ts

📄 CodeRabbit inference engine (.cursor/rules/swapper.mdc)

packages/swapper/src/swappers/*/*.ts: All swappers must implement the Swapper interface from packages/swapper/src/types.ts
Implement filterAssetIdsBySellable method to filter assets by supported chain IDs in the sell property
Implement filterBuyAssetsBySellAssetId method to filter assets by supported chain IDs in the buy property
Reuse executeEvmTransaction utility for EVM-based swappers instead of implementing custom transaction execution

Files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
packages/swapper/src/swappers/*/endpoints.ts

📄 CodeRabbit inference engine (.cursor/rules/swapper.mdc)

packages/swapper/src/swappers/*/endpoints.ts: All swapper API implementations must implement the SwapperApi interface from packages/swapper/src/types.ts
Reuse checkEvmSwapStatus utility for checking EVM swap status instead of implementing custom status checks

Files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
{.env.development,.env.production}

📄 CodeRabbit inference engine (CLAUDE.md)

Use .env.development for dev-only features and .env.production for prod settings

Files:

  • .env.development
🧠 Learnings (30)
📓 Common learnings
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/RFOX/components/Stake/components/StakeSummary.tsx:112-114
Timestamp: 2025-08-22T13:00:44.879Z
Learning: NeOMakinG prefers to keep PR changes minimal and focused on the core objectives, avoiding cosmetic or defensive code improvements that aren't directly related to the PR scope, even when they would improve robustness.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10128
File: .cursor/rules/error-handling.mdc:266-274
Timestamp: 2025-07-29T10:35:22.059Z
Learning: NeOMakinG prefers less nitpicky suggestions on documentation and best practices files, finding overly detailed suggestions on minor implementation details (like console.error vs logger.error) too granular for cursor rules documentation.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/pages/Dashboard/components/AccountList/AccountTable.tsx:60-0
Timestamp: 2025-09-02T08:34:08.157Z
Learning: NeOMakinG prefers code review comments to focus only on actual PR changes, not pre-existing code issues, unless there are critical security or correctness concerns directly related to the new functionality.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10234
File: src/components/MultiHopTrade/hooks/useGetTradeQuotes/hooks/useTrackTradeQuotes.ts:42-86
Timestamp: 2025-08-08T11:41:22.794Z
Learning: NeOMakinG prefers not to include refactors in move-only PRs; such suggestions should be deferred to follow-up issues instead of being applied within the same PR.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/components/Table/Table.theme.ts:177-180
Timestamp: 2025-09-02T12:38:46.940Z
Learning: NeOMakinG prefers to defer technical debt and CSS correctness issues (like improper hover selectors) to follow-up PRs when the current PR is already large and focused on major feature implementation, even when the issues are valid from a usability/technical perspective.
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to src/config.ts : Default values always come from environment variables prefixed with `VITE_FEATURE_`

Applied to files:

  • .env
  • .env.development
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: To add a new feature flag: (1) Add to `FeatureFlags` type in `src/state/slices/preferencesSlice/preferencesSlice.ts`, (2) Add environment variable validation in `src/config.ts`, (3) Add to initial state in `preferencesSlice.ts`, (4) Add to test mock in `src/test/mocks/store.ts`, (5) Set appropriate values in `.env`, `.env.development`, and `.env.production`

Applied to files:

  • .env
📚 Learning: 2025-09-09T06:01:24.130Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10424
File: .env.production:3-3
Timestamp: 2025-09-09T06:01:24.130Z
Learning: In Vite, environment variables have a fallback mechanism where .env.production takes precedence over .env, but variables defined only in .env will still be available in the production environment if not overridden in .env.production.

Applied to files:

  • .env
📚 Learning: 2025-11-12T12:18:00.863Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11016
File: packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts:109-145
Timestamp: 2025-11-12T12:18:00.863Z
Learning: NEAR Intents swapper: The NEAR 1Click API does not provide gas limit estimation logic like other swappers (e.g., magic gasLimit fields). For ERC20 token swaps in getTradeQuote, accurate fee estimation requires token approval and sufficient balance; without these prerequisites, fees may display as 0 or use inaccurate native transfer estimates. This is a known limitation of the NEAR Intents integration.

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Reuse executeEvmTransaction utility for EVM-based swappers instead of implementing custom transaction execution

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
  • packages/swapper/src/types.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/endpoints.ts : All swapper API implementations must implement the SwapperApi interface from packages/swapper/src/types.ts

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
  • packages/swapper/src/types.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/endpoints.ts : Reuse checkEvmSwapStatus utility for checking EVM swap status instead of implementing custom status checks

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/**/*.test.ts : Write unit tests for swapper methods and API endpoints

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
  • packages/swapper/src/types.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/index.ts : Export unique functions and types from packages/swapper/src/index.ts only if needed for external consumption

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
  • packages/swapper/src/types.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/**/*.ts : Use TypeScript with explicit types (e.g., SupportedChainIds) for all code in the Swapper system

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
  • packages/swapper/src/types.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/**/*.ts : Avoid side effects in swap logic; ensure swap methods are deterministic and stateless

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
  • packages/swapper/src/types.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/utils/constants.ts : Define supported chain IDs for each swapper in utils/constants.ts with both 'sell' and 'buy' properties following the pattern: SupportedChainIds type

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
  • packages/swapper/src/types.ts
📚 Learning: 2025-11-12T12:49:17.895Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11016
File: packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts:109-125
Timestamp: 2025-11-12T12:49:17.895Z
Learning: In packages/chain-adapters/src/evm/utils.ts, the getErc20Data function already includes a guard that returns an empty string when contractAddress is undefined (line 8: `if (!contractAddress) return ''`). This built-in handling means callers don't need to conditionally invoke getErc20Data—it safely handles both ERC20 tokens and native assets.

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Import types from `shapeshiftoss/caip` for chain/account/asset IDs

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
  • packages/swapper/src/types.ts
📚 Learning: 2025-10-23T14:27:19.073Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10857
File: src/plugins/walletConnectToDapps/eventsManager/useWalletConnectEventsHandler.ts:101-104
Timestamp: 2025-10-23T14:27:19.073Z
Learning: In WalletConnect wallet_switchEthereumChain and wallet_addEthereumChain requests, the chainId parameter is always present as per the protocol spec. Type guards checking for missing chainId in these handlers (like `if (!evmNetworkIdHex) return`) are solely for TypeScript compiler satisfaction, not real runtime edge cases.

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
📚 Learning: 2025-11-24T21:20:17.804Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-11-24T21:20:17.804Z
Learning: Applies to **/swapper{s,}/**/*.{ts,tsx} : ALWAYS use `makeSwapErrorRight` for swapper errors with `TradeQuoteError` enum for error codes and provide detailed error information

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
  • packages/swapper/src/types.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Implement filterBuyAssetsBySellAssetId method to filter assets by supported chain IDs in the buy property

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts
  • packages/swapper/src/types.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/**/*.ts : Use PascalCase for types, interfaces, and enums in the Swapper system

Applied to files:

  • packages/swapper/src/types.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : All swappers must implement the Swapper interface from packages/swapper/src/types.ts

Applied to files:

  • packages/swapper/src/types.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/**/*.ts : Validate inputs and log errors for debugging in Swapper system implementations

Applied to files:

  • packages/swapper/src/types.ts
📚 Learning: 2025-09-12T13:44:17.019Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/hooks/useSimulateEvmTransaction.ts:0-0
Timestamp: 2025-09-12T13:44:17.019Z
Learning: gomesalexandre prefers letting chain adapter errors throw naturally in useSimulateEvmTransaction rather than adding explicit error handling for missing adapters, consistent with his fail-fast approach and dismissal of defensive validation as "stale" in WalletConnect transaction simulation flows.

Applied to files:

  • packages/swapper/src/types.ts
📚 Learning: 2025-09-12T09:48:46.305Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/StructuredMessage/StructuredMessage.tsx:0-0
Timestamp: 2025-09-12T09:48:46.305Z
Learning: In WalletConnect signing flows dealing with structured message data (like StructuredField.value in StructuredMessage.tsx), gomesalexandre prefers using `any` type for values representing dynamic Solidity types from external API responses, consistent with their approach to other external API parsing in WalletConnect flows.

Applied to files:

  • packages/swapper/src/types.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Implement filterAssetIdsBySellable method to filter assets by supported chain IDs in the sell property

Applied to files:

  • packages/swapper/src/types.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/constants.ts : Register new swappers in packages/swapper/src/constants.ts with an entry in the swappers registry mapping SwapperName enum to swapper implementation

Applied to files:

  • packages/swapper/src/types.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/**/*.ts : Adhere to the Swapper directory structure: each swapper resides in packages/swapper/src/swappers/<SwapperName>/ with required files (SwapperName.ts, endpoints.ts, types.ts, utils/constants.ts, utils/helpers.ts)

Applied to files:

  • packages/swapper/src/types.ts
📚 Learning: 2025-11-03T22:31:30.786Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10985
File: packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.ts:0-0
Timestamp: 2025-11-03T22:31:30.786Z
Learning: In packages/swapper/src/swappers/PortalsSwapper, the rate and quote files intentionally use different approaches for calculating buyAmountBeforeSlippageCryptoBaseUnit: getPortalsTradeRate.tsx uses minOutputAmount / (1 - buffer) for conservative estimates, while getPortalsTradeQuote.ts uses outputAmount / (1 - buffer) for final quote display. This difference is validated by on-chain simulation testing and is intentional.

Applied to files:

  • packages/swapper/src/types.ts
📚 Learning: 2025-07-29T15:04:28.083Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10139
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx:109-115
Timestamp: 2025-07-29T15:04:28.083Z
Learning: In src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx, the component is used under an umbrella that 100% of the time contains the quote, making the type assertion `activeTradeQuote?.steps[currentHopIndex] as TradeQuoteStep` safe. Adding conditional returns before hooks would violate React's Rules of Hooks.

Applied to files:

  • packages/swapper/src/types.ts
📚 Learning: 2025-08-04T16:02:27.360Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10171
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandedStepperSteps.tsx:458-458
Timestamp: 2025-08-04T16:02:27.360Z
Learning: In multi-hop swap transactions, last hop sell transactions might not be detected by the swapper (unlike buy transactions which are always known immediately). The conditional stepSource logic for last hop buy transactions (`isLastHopSellTxSeen ? stepSource : undefined`) serves as defensive programming for future multi-hop support with intermediate chains, even though multi-hop functionality is not currently supported in production.

Applied to files:

  • packages/swapper/src/types.ts
📚 Learning: 2025-09-12T12:08:15.823Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/WalletConnectModalManager.tsx:226-233
Timestamp: 2025-09-12T12:08:15.823Z
Learning: In WalletConnect dApps integration, EthSignTransactionCallRequest and EthSendTransactionCallRequest have identical transaction parameter structures (from, to, data, etc.) per JSON-RPC spec - only the method field differs. This makes it safe to type-cast between them when passing transaction parameters to components like EIP155TransactionConfirmation that process the underlying transaction data regardless of the originating method.

Applied to files:

  • packages/swapper/src/types.ts
🪛 dotenv-linter (4.0.0)
.env.development

[warning] 88-88: [UnorderedKey] The VITE_FEATURE_TRON key should go before the VITE_FEATURE_WC_DIRECT_CONNECTION key

(UnorderedKey)

⏰ 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). (1)
  • GitHub Check: Install and Cache
🔇 Additional comments (7)
.env (1)

67-67: Verify complete feature flag implementation.

Per the feature flag integration checklist, ensure that:

  • FeatureFlags type in src/state/slices/preferencesSlice/preferencesSlice.ts includes VITE_FEATURE_TRON
  • Environment variable validation in src/config.ts includes VITE_FEATURE_TRON and VITE_TRON_NODE_URL
  • Initial state in preferencesSlice.ts includes the TRON feature flag
  • Test mock in src/test/mocks/store.ts includes the TRON feature flag
  • .env.production includes appropriate values for VITE_FEATURE_TRON and VITE_TRON_NODE_URL (if TRON is production-ready)
packages/swapper/src/types.ts (4)

3-12: Tron and Polyglot type imports are consistent with existing adapter patterns

Importing tron alongside solana, adding TronChainId, and pulling InterpolationOptions from node-polyglot cleanly extend the existing type surface without changing behavior. As long as tron.TronSignTx and TronChainId remain stable in their respective packages, this should type-check fine.

Please confirm yarn type-check passes against the current versions of @shapeshiftoss/chain-adapters, @shapeshiftoss/types, and node-polyglot. Based on learnings, keeping this scoped to new Tron support matches the PR’s intent.

Also applies to: 13-25, 30-33


166-187: Tron trade quote/rate input types are well-aligned with existing chains

The new GetTronTradeQuoteInputBase / GetTronTradeQuoteInput / GetTronTradeRateInput types and their inclusion in GetTradeQuoteInput, GetTradeRateInput, and GetTradeQuoteInputWithWallet mirror the Cosmos/EVM conventions and correctly narrow chainId to TronChainId. This gives Tron first-class support in the public quote/rate inputs without impacting existing callers.

Also applies to: 191-199, 204-211, 212-227, 246-263


264-295: SwapperDeps extension with TronSwapperDeps matches the existing dependency model

Defining TronSwapperDeps and intersecting it into SwapperDeps alongside Solana/EVM/UTXO/Cosmos keeps the dependency shape consistent and ensures any swapper API using Tron unsigned tx helpers has access to assertGetTronChainAdapter. This is a clean, minimal way to wire in Tron without refactoring the broader dependency model.


534-537: Tron unsigned-transaction and execution types cleanly mirror existing flows

TronTransactionExecutionProps, TronAccountMetadata, GetUnsignedTronTransactionArgs, TronTransactionExecutionInput, and the executeTronTransaction, getUnsignedTronTransaction, and getTronTransactionFees additions to Swapper/SwapperApi closely follow the established EVM/Solana patterns while correctly using tron.TronSignTx. This should make Tron execution plug into the existing tradeExecution pipeline with minimal special-casing.

Also applies to: 540-541, 563-566, 619-647, 652-666, 667-672, 690-713

packages/swapper/src/swappers/NearIntentsSwapper/endpoints.ts (2)

193-194: The review comment is incorrect. The imported Tron utilities properly handle NearIntents-specific logic.

The Tron utilities (getUnsignedTronTransaction and getTronTransactionFees) are not generic utilities that ignore NearIntents-specific data. They:

  1. Validate correctly: Both call isExecutableTradeQuote() and getExecutableTradeStep() (lines 12-14 and 8-10 respectively)
  2. Handle nearIntentsSpecific: getUnsignedTronTransaction explicitly extracts nearIntentsSpecific from the step (line 16) and uses its depositAddress as a fallback destination (line 20)
  3. Follow the established pattern: getTronTransactionFees mirrors the Solana and UTXO implementations by checking and returning step.feeData.networkFeeCryptoBaseUnit

The utilities were designed to be reusable across swapper implementations while correctly handling both relay and NearIntents-specific workflows. Using imported utilities here is consistent with DRY principles and does not represent a pattern break—it's a better approach than duplicating logic inline.


5-6: Based on my verification, I have enough information to provide the rewritten review comment. The investigation shows that the imported Tron utilities do handle nearIntentsSpecific properly, contrary to what the original review comment assumed.


The imported Tron utilities correctly handle NearIntents-specific logic.

Both getUnsignedTronTransaction and getTronTransactionFees properly validate the trade quote and extract the step. getUnsignedTronTransaction explicitly uses nearIntentsSpecific?.depositAddress (line 20 of its implementation) as a fallback destination when relayTransactionMetadata.to is unavailable, and validates that a destination exists (line 21). getTronTransactionFees doesn't require nearIntentsSpecific since it only returns the network fee from step.feeData.

While the pattern differs from inline methods (which mandate nearIntentsSpecific with explicit checks), the Tron implementation is functionally correct and intentionally uses a fallback approach to support both relay and intent-based transaction flows.

- Fix TxStatus import to use public API (@shapeshiftoss/unchained-client)
- Add defensive checks to isTronChainAdapter type guard
- Guard against unexpected RPC responses in getTronTransactionStatus
- Fix switch case scope leakage in useSendActionSubscriber
- Add error logging for TRC20 fetch failures
- Preserve error context in fee estimation
Copy link
Contributor

@gomesalexandre gomesalexandre left a comment

Choose a reason for hiding this comment

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

Another day another gucci https://jam.dev/c/75b6e0bb-c1c6-49c1-95ef-744269c6842e - also used this PR to confirm #11227 is happy so i'll yeet that bump PR

@gomesalexandre gomesalexandre enabled auto-merge (squash) November 28, 2025 11:15
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx (1)

31-56: Fix timer type for pollingIntervalsRef to avoid TS type errors

useRef<Map<string, NodeJS.Timeout>> doesn’t match the browser setInterval return type (which is number in lib.dom.d.ts), so this will fail yarn type-check in a web build.

Use ReturnType<typeof setInterval> so the type stays correct across environments:

-  const pollingIntervalsRef = useRef<Map<string, NodeJS.Timeout>>(new Map())
+  const pollingIntervalsRef =
+    useRef<Map<string, ReturnType<typeof setInterval>>>(new Map())

The rest of the getAccount/SECOND_CLASS_CHAINS completion wiring looks good.

🧹 Nitpick comments (4)
packages/unchained-client/src/tron/api.ts (4)

97-106: Log TRC20 balance fetch failures for debugging consistency.

The catch block at line 103 silently returns '0' without logging, which is inconsistent with the TRC20 fetch error logging added at line 87. This makes it difficult to diagnose balance fetch issues.

Apply this diff to add logging:

-    } catch (_err) {
+    } catch (err) {
+      console.error('Failed to fetch TRC20 balance:', err)
       return '0'
     }

As per coding guidelines and consistency with line 87.


188-201: Consider logging chain price fetch failures.

The private helper getChainPrices() silently returns default values when fetching chain parameters fails. While the defaults are sensible, logging would help diagnose configuration or connectivity issues.

Apply this diff:

-    } catch (_err) {
+    } catch (err) {
+      console.error('Failed to fetch chain prices, using defaults:', err)
       return { bandwidthPrice: 1000, energyPrice: 420 }
     }

217-245: Log TRC20 transfer fee estimation failures for debugging.

The catch block at line 242 silently returns a default fee of '31000000' without logging. This makes it difficult to diagnose fee estimation failures and understand why the default is being used.

Apply this diff to add logging:

-    } catch (_err) {
+    } catch (err) {
+      console.error('Failed to estimate TRC20 transfer fee:', err)
       return '31000000'
     }

As per coding guidelines and consistency with other error logging in this file.


247-276: Consider logging priority fee fetch failures.

The catch block at line 266 silently returns default fees without logging. While the defaults are reasonable, logging would help diagnose issues with fetching bandwidth prices.

Apply this diff:

-    } catch (_err) {
+    } catch (err) {
+      console.error('Failed to fetch priority fees, using defaults:', err)
       const defaultFee = '268000'
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0af9799 and aa73b51.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (7)
  • package.json (2 hunks)
  • packages/caip/src/adapters/coingecko/index.test.ts (2 hunks)
  • packages/caip/src/adapters/coingecko/utils.test.ts (1 hunks)
  • packages/unchained-client/src/tron/api.ts (1 hunks)
  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx (2 hunks)
  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx (4 hunks)
  • src/lib/utils/tron.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/utils/tron.ts
  • package.json
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Never assume a library is available - always check imports/package.json first
Prefer composition over inheritance
Write self-documenting code with clear variable and function names
Keep functions small and focused on a single responsibility
Avoid deep nesting - use early returns instead
Prefer procedural and easy to understand code
Never expose, log, or commit secrets, API keys, or credentials
Validate all inputs, especially user inputs
Handle errors gracefully with meaningful messages
Don't silently catch and ignore exceptions
Log errors appropriately for debugging
Provide fallback behavior when possible
Use appropriate data structures for the task
Never add code comments unless explicitly requested
When modifying code, do not add comments that reference previous implementations or explain what changed. Comments should only describe the current logic and functionality.
Use meaningful names for branches, variables, and functions
Always run yarn lint --fix and yarn type-check after making changes
Avoid let variable assignments - prefer const with inline IIFE switch statements or extract to functions for conditional logic

Files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • packages/caip/src/adapters/coingecko/utils.test.ts
  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
  • packages/caip/src/adapters/coingecko/index.test.ts
  • packages/unchained-client/src/tron/api.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Avoid useEffect where practical - use it only when necessary and following best practices
Avoid 'any' types - use specific type annotations instead
For default values with user overrides, use computed values (useMemo) instead of useEffect - pattern: userSelected ?? smartDefault ?? fallback
When function parameters are unused due to interface requirements, refactor the interface or implementation to remove them rather than prefixing with underscore
Sanitize data before displaying to prevent XSS
Memoize aggressively - wrap component variables in useMemo and callbacks in useCallback where possible
For static JSX icon elements (e.g., <TbCopy />) that don't depend on state/props, define them as constants outside the component to avoid re-renders instead of using useMemo
Account for light/dark mode using useColorModeValue hook
Account for responsive mobile designs in all UI components
When applying styles, use the existing standards and conventions of the codebase
Use Chakra UI components and conventions
All copy/text must use translation keys - never hardcode strings
Use the translation hook: useTranslate() from react-polyglot
Use useFeatureFlag('FlagName') hook to access feature flag values in components
Prefer type over interface for type definitions
Use strict typing - avoid any
Use Nominal types for domain identifiers (e.g., WalletId, AccountId)
Import types from @shapeshiftoss/caip for chain/account/asset IDs
Use useAppSelector for Redux state
Use useAppDispatch for Redux actions
Memoize expensive computations with useMemo
Memoize callbacks with useCallback

**/*.{ts,tsx}: Use Result<T, E> pattern for error handling in swappers and APIs; ALWAYS use Ok() and Err() from @sniptt/monads; AVOID throwing within swapper API implementations
ALWAYS use custom error classes from @shapeshiftoss/errors with meaningful error codes for internationalization and relevant details in error objects
ALWAYS wrap async op...

Files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • packages/caip/src/adapters/coingecko/utils.test.ts
  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
  • packages/caip/src/adapters/coingecko/index.test.ts
  • packages/unchained-client/src/tron/api.ts
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

**/*.{tsx,jsx}: ALWAYS wrap React components in error boundaries and provide user-friendly fallback components with error logging
ALWAYS use useErrorToast hook for displaying errors with translated error messages and handle different error types appropriately

Use PascalCase for React component names and match the component name to the file name

Files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/naming-conventions.mdc)

**/*.{js,jsx,ts,tsx}: Use camelCase for variables, functions, and methods with descriptive names that explain the purpose
Use verb prefixes for functions that perform actions (e.g., fetch, validate, execute, update, calculate)
Use UPPER_SNAKE_CASE for constants and configuration values with descriptive names
Use handle prefix for event handlers with descriptive names in camelCase
Use descriptive boolean variable names with is, has, can, should prefixes
Use named exports for components, functions, and utilities instead of default exports
Use descriptive import names and avoid renaming imports unless necessary
Avoid non-descriptive variable names like data, item, obj, and single-letter variable names except in loops
Avoid abbreviations in names unless they are widely understood
Avoid generic function names like fn, func, or callback

Files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • packages/caip/src/adapters/coingecko/utils.test.ts
  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
  • packages/caip/src/adapters/coingecko/index.test.ts
  • packages/unchained-client/src/tron/api.ts
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)

**/*.{jsx,tsx}: ALWAYS use useMemo for expensive computations, object/array creations, and filtered data
ALWAYS use useMemo for derived values and computed properties
ALWAYS use useMemo for conditional values and simple transformations
ALWAYS use useCallback for event handlers and functions passed as props
ALWAYS use useCallback for any function that could be passed as a prop or dependency
ALWAYS include all dependencies in useEffect, useMemo, useCallback dependency arrays
NEVER use // eslint-disable-next-line react-hooks/exhaustive-deps unless absolutely necessary, and ALWAYS explain why dependencies are excluded if using eslint disable
ALWAYS use named exports for components; NEVER use default exports for components
KEEP component files under 200 lines when possible; BREAK DOWN large components into smaller, reusable pieces
EXTRACT complex logic into custom hooks
ALWAYS wrap components in error boundaries for production
ALWAYS handle async errors properly in async operations
ALWAYS provide user-friendly error messages in error handling
ALWAYS use virtualization for lists with 100+ items
ALWAYS implement proper key props for list items
ALWAYS lazy load heavy components using React.lazy for code splitting
ALWAYS use Suspense wrapper for lazy loaded components
USE local state for component-level state; LIFT state up when needed across multiple components; USE Context for avoiding prop drilling; USE Redux only for global state shared across multiple places
Wrap components receiving props with memo for performance optimization

Files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/react-best-practices.mdc)

Ensure TypeScript types are explicit and proper; avoid use of any type

Files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx,js,jsx}: Write tests for critical business logic
Test edge cases and error conditions
Use descriptive test names that explain behavior
Keep tests isolated and independent
Mock external dependencies appropriately

Files:

  • packages/caip/src/adapters/coingecko/utils.test.ts
  • packages/caip/src/adapters/coingecko/index.test.ts
🧠 Learnings (77)
📓 Common learnings
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/**/*.ts : Use TypeScript with explicit types (e.g., SupportedChainIds) for all code in the Swapper system
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/RFOX/components/Stake/components/StakeSummary.tsx:112-114
Timestamp: 2025-08-22T13:00:44.879Z
Learning: NeOMakinG prefers to keep PR changes minimal and focused on the core objectives, avoiding cosmetic or defensive code improvements that aren't directly related to the PR scope, even when they would improve robustness.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10128
File: .cursor/rules/error-handling.mdc:266-274
Timestamp: 2025-07-29T10:35:22.059Z
Learning: NeOMakinG prefers less nitpicky suggestions on documentation and best practices files, finding overly detailed suggestions on minor implementation details (like console.error vs logger.error) too granular for cursor rules documentation.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/pages/Dashboard/components/AccountList/AccountTable.tsx:60-0
Timestamp: 2025-09-02T08:34:08.157Z
Learning: NeOMakinG prefers code review comments to focus only on actual PR changes, not pre-existing code issues, unless there are critical security or correctness concerns directly related to the new functionality.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10234
File: src/components/MultiHopTrade/hooks/useGetTradeQuotes/hooks/useTrackTradeQuotes.ts:42-86
Timestamp: 2025-08-08T11:41:22.794Z
Learning: NeOMakinG prefers not to include refactors in move-only PRs; such suggestions should be deferred to follow-up issues instead of being applied within the same PR.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/components/Table/Table.theme.ts:177-180
Timestamp: 2025-09-02T12:38:46.940Z
Learning: NeOMakinG prefers to defer technical debt and CSS correctness issues (like improper hover selectors) to follow-up PRs when the current PR is already large and focused on major feature implementation, even when the issues are valid from a usability/technical perspective.
📚 Learning: 2025-08-08T11:40:55.734Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10234
File: src/components/MultiHopTrade/components/TradeConfirm/TradeConfirm.tsx:41-41
Timestamp: 2025-08-08T11:40:55.734Z
Learning: In MultiHopTrade confirm flow (src/components/MultiHopTrade/components/TradeConfirm/TradeConfirm.tsx and related hooks), there is only one active trade per flow. Because of this, persistent (module/Redux) dedupe for QuotesReceived in useTrackTradeQuotes is not necessary; the existing ref-based dedupe is acceptable.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
📚 Learning: 2025-07-29T15:04:28.083Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10139
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx:109-115
Timestamp: 2025-07-29T15:04:28.083Z
Learning: In src/components/MultiHopTrade/components/TradeConfirm/components/ExpandableStepperSteps.tsx, the component is used under an umbrella that 100% of the time contains the quote, making the type assertion `activeTradeQuote?.steps[currentHopIndex] as TradeQuoteStep` safe. Adding conditional returns before hooks would violate React's Rules of Hooks.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
📚 Learning: 2025-11-03T22:31:30.786Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10985
File: packages/swapper/src/swappers/PortalsSwapper/getPortalsTradeQuote/getPortalsTradeQuote.ts:0-0
Timestamp: 2025-11-03T22:31:30.786Z
Learning: In packages/swapper/src/swappers/PortalsSwapper, the rate and quote files intentionally use different approaches for calculating buyAmountBeforeSlippageCryptoBaseUnit: getPortalsTradeRate.tsx uses minOutputAmount / (1 - buffer) for conservative estimates, while getPortalsTradeQuote.ts uses outputAmount / (1 - buffer) for final quote display. This difference is validated by on-chain simulation testing and is intentional.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
📚 Learning: 2025-08-08T11:41:36.971Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10234
File: src/components/MultiHopTrade/hooks/useGetTradeQuotes/hooks/useTrackTradeQuotes.ts:88-109
Timestamp: 2025-08-08T11:41:36.971Z
Learning: In MultiHopTrade Confirm flow (src/components/MultiHopTrade/components/TradeConfirm/TradeConfirm.tsx), the Confirm route does not remount; navigating away goes to the swapper input page. Therefore, persistent deduplication across remounts for quote tracking is unnecessary; a ref-based single-mount dedupe is sufficient.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
📚 Learning: 2025-11-24T21:20:17.804Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-11-24T21:20:17.804Z
Learning: Applies to **/swapper{s,}/**/*.{ts,tsx} : ALWAYS use `makeSwapErrorRight` for swapper errors with `TradeQuoteError` enum for error codes and provide detailed error information

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Reuse executeEvmTransaction utility for EVM-based swappers instead of implementing custom transaction execution

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Implement filterBuyAssetsBySellAssetId method to filter assets by supported chain IDs in the buy property

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • packages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/utils/constants.ts : Define supported chain IDs for each swapper in utils/constants.ts with both 'sell' and 'buy' properties following the pattern: SupportedChainIds type

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • packages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Import types from `shapeshiftoss/caip` for chain/account/asset IDs

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/*/*.ts : Implement filterAssetIdsBySellable method to filter assets by supported chain IDs in the sell property

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • packages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-08-26T19:04:38.672Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 10369
File: packages/chain-adapters/src/cosmossdk/CosmosSdkBaseAdapter.ts:167-176
Timestamp: 2025-08-26T19:04:38.672Z
Learning: In packages/chain-adapters/src/cosmossdk/CosmosSdkBaseAdapter.ts, when processing assets from data.assets.reduce(), the team prefers using empty catch blocks to gracefully skip any assets that fail processing, rather than specific error type handling, to avoid useless noise and ensure robust asset filtering.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
📚 Learning: 2025-09-12T13:44:17.019Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/hooks/useSimulateEvmTransaction.ts:0-0
Timestamp: 2025-09-12T13:44:17.019Z
Learning: gomesalexandre prefers letting chain adapter errors throw naturally in useSimulateEvmTransaction rather than adding explicit error handling for missing adapters, consistent with his fail-fast approach and dismissal of defensive validation as "stale" in WalletConnect transaction simulation flows.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
📚 Learning: 2025-11-12T12:49:17.895Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11016
File: packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts:109-125
Timestamp: 2025-11-12T12:49:17.895Z
Learning: In packages/chain-adapters/src/evm/utils.ts, the getErc20Data function already includes a guard that returns an empty string when contractAddress is undefined (line 8: `if (!contractAddress) return ''`). This built-in handling means callers don't need to conditionally invoke getErc20Data—it safely handles both ERC20 tokens and native assets.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
📚 Learning: 2025-11-19T16:59:50.569Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11012
File: src/context/WalletProvider/Vultisig/components/Connect.tsx:24-59
Timestamp: 2025-11-19T16:59:50.569Z
Learning: In src/context/WalletProvider/*/components/Connect.tsx files across the ShapeShift web codebase, the established pattern for handling null/undefined adapter from getAdapter() is to simply check `if (adapter) { ... }` without an else clause. All wallet Connect components (Coinbase, Keplr, Phantom, Ledger, MetaMask, WalletConnectV2, KeepKey, Vultisig) follow this pattern—they reset loading state after the if block but do not show error messages when adapter is null. This is an intentional design decision and should be maintained for consistency.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
📚 Learning: 2025-08-04T16:02:27.360Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10171
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandedStepperSteps.tsx:458-458
Timestamp: 2025-08-04T16:02:27.360Z
Learning: In multi-hop swap transactions, last hop sell transactions might not be detected by the swapper (unlike buy transactions which are always known immediately). The conditional stepSource logic for last hop buy transactions (`isLastHopSellTxSeen ? stepSource : undefined`) serves as defensive programming for future multi-hop support with intermediate chains, even though multi-hop functionality is not currently supported in production.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
📚 Learning: 2025-08-04T15:36:25.122Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10171
File: src/components/MultiHopTrade/components/TradeConfirm/components/ExpandedStepperSteps.tsx:458-458
Timestamp: 2025-08-04T15:36:25.122Z
Learning: In swap transaction handling, buy transaction hashes should always use the swapper's explorer (stepSource) because they are known by the swapper immediately upon swap execution. The conditional logic for using default explorers applies primarily to sell transactions which need to be detected/indexed by external systems like Thorchain or ViewBlock.

Applied to files:

  • src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/**/*.test.ts : Write unit tests for swapper methods and API endpoints

Applied to files:

  • packages/caip/src/adapters/coingecko/utils.test.ts
📚 Learning: 2025-11-20T12:00:45.005Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11078
File: src/setupVitest.ts:11-15
Timestamp: 2025-11-20T12:00:45.005Z
Learning: In shapeshift/web, src/setupVitest.ts must redirect 'ethers' to 'ethers5' for shapeshiftoss/hdwallet-trezor (and -trezor-connect), same as ledger and shapeshift-multichain. Removing 'trezor' from the regex causes CI/Vitest failures due to ethers v6 vs v5 API differences.

Applied to files:

  • packages/caip/src/adapters/coingecko/utils.test.ts
  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-08-17T21:53:03.806Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10290
File: scripts/generateAssetData/color-map.json:41-47
Timestamp: 2025-08-17T21:53:03.806Z
Learning: In the ShapeShift web codebase, native assets (using CAIP-19 slip44 namespace like eip155:1/slip44:60, bip122:.../slip44:..., cosmos:.../slip44:...) are manually hardcoded and not generated via the automated asset generation script. Only ERC20/BEP20 tokens go through the asset generation process. The validation scripts should only validate generated assets, not manually added native assets.

Applied to files:

  • packages/caip/src/adapters/coingecko/utils.test.ts
  • packages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-08-22T15:07:18.021Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 10326
File: src/hooks/useActionCenterSubscribers/useThorchainLpActionSubscriber.tsx:37-41
Timestamp: 2025-08-22T15:07:18.021Z
Learning: In src/hooks/useActionCenterSubscribers/useThorchainLpActionSubscriber.tsx, kaladinlight prefers not to await the upsertBasePortfolio call in the Base chain handling block, indicating intentional fire-and-forget behavior for Base portfolio upserts in the THORChain LP completion flow.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
📚 Learning: 2025-08-22T13:16:12.721Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/RFOX/hooks/useRfoxRewardDistributionActionSubscriber.tsx:104-105
Timestamp: 2025-08-22T13:16:12.721Z
Learning: In src/pages/RFOX/hooks/useRfoxRewardDistributionActionSubscriber.tsx, the guard `if (!actions[actionId]) return` before upserting completed reward distributions is intentional product behavior. NeOMakinG confirmed that the system should only show completion notifications for reward distributions that were previously seen in a pending state, not for distributions the user missed during the pending phase.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
📚 Learning: 2025-08-22T14:59:04.889Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 10326
File: src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx:105-111
Timestamp: 2025-08-22T14:59:04.889Z
Learning: In the ShapeShift web Base chain handling, the await pattern inside forEach in useGenericTransactionSubscriber is intentional to delay the entire action completion flow (not just fetchBasePortfolio) for Base chain transactions. The user kaladinlight wants everything below the Base portfolio refresh - including dispatch, query invalidation, and toast notifications - to also be delayed by ~10 seconds to accommodate Base's degraded node state.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
📚 Learning: 2025-08-25T12:58:39.547Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/Layout/Header/ActionCenter/components/Notifications/RewardDistributionNotification.tsx:69-70
Timestamp: 2025-08-25T12:58:39.547Z
Learning: In RewardDistributionNotification component (src/components/Layout/Header/ActionCenter/components/Notifications/RewardDistributionNotification.tsx), NeOMakinG confirmed that action is expected to always be defined when the component renders, so defensive guards against undefined action are not needed.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
📚 Learning: 2025-08-22T13:02:58.824Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/pages/RFOX/hooks/useRfoxRewardDistributionActionSubscriber.tsx:33-41
Timestamp: 2025-08-22T13:02:58.824Z
Learning: In src/pages/RFOX/hooks/useRfoxRewardDistributionActionSubscriber.tsx, NeOMakinG declined optimizing useMemo dependencies to depend on lifetimeRewardDistributionsQuery.data instead of the entire query object, indicating indifference toward this type of performance optimization.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
📚 Learning: 2025-08-14T17:54:32.563Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/ReusableLpStatus.tsx:97-108
Timestamp: 2025-08-14T17:54:32.563Z
Learning: In ReusableLpStatus component (src/pages/ThorChainLP/components/ReusableLpStatus/ReusableLpStatus.tsx), the txAssets dependency is stable from first render because poolAsset, baseAsset, actionSide, and action are all defined first render, making the current txAssetsStatuses initialization pattern safe without needing useEffect synchronization.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
📚 Learning: 2025-08-22T12:58:26.590Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10323
File: src/components/Layout/Header/ActionCenter/components/GenericTransactionActionCard.tsx:108-111
Timestamp: 2025-08-22T12:58:26.590Z
Learning: In the RFOX GenericTransactionDisplayType flow in src/components/Layout/Header/ActionCenter/components/GenericTransactionActionCard.tsx, the txHash is always guaranteed to be present according to NeOMakinG, so defensive null checks for txLink are not needed in this context.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
📚 Learning: 2025-09-08T15:53:09.362Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10442
File: src/components/TradeAssetSearch/components/GroupedAssetList/GroupedAssetList.tsx:34-35
Timestamp: 2025-09-08T15:53:09.362Z
Learning: In DefaultAssetList.tsx, the GroupedAssetList component already receives the activeChainId prop correctly on line ~58, contrary to automated analysis that may flag it as missing.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Avoid `let` variable assignments - prefer `const` with inline IIFE switch statements or extract to functions for conditional logic

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/**/*.ts : Use TypeScript with explicit types (e.g., SupportedChainIds) for all code in the Swapper system

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-12T10:44:46.723Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/content/SendTransactionContent.tsx:0-0
Timestamp: 2025-09-12T10:44:46.723Z
Learning: gomesalexandre dismissed a clipboard error handling suggestion in PR #10461 for SendTransactionContent.tsx, demonstrating that the current navigator.clipboard.writeText implementation works as expected and preferring to keep it simple without additional try/catch error handling.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-12T10:35:51.632Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:33-45
Timestamp: 2025-09-12T10:35:51.632Z
Learning: gomesalexandre consistently dismisses CodeRabbit suggestions about replacing console.error/console.warn with structured logging in API integration code, preferring simple console logging for debugging Tenderly transaction simulation APIs in WalletConnect flows.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-10T15:35:46.223Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/components/modals/EIP155SignTypedDataConfirmation.tsx:55-55
Timestamp: 2025-09-10T15:35:46.223Z
Learning: gomesalexandre prefers fail-fast early returns over graceful degradation when critical data is missing in WalletConnect flows (like peer metadata in EIP155SignTypedDataConfirmation.tsx). He favors "safety first, always double-wrap" approach and believes missing peer metadata indicates bigger problems that should be surfaced explicitly rather than masked with partial UI rendering.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-08-07T11:22:16.983Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/lib/moralis.ts:47-85
Timestamp: 2025-08-07T11:22:16.983Z
Learning: gomesalexandre prefers console.error over structured logging for Moralis API integration debugging, as they find it more conventional and prefer to examine XHR requests directly rather than rely on structured logs for troubleshooting.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-12T09:58:57.389Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP155TransactionConfirmation.tsx:0-0
Timestamp: 2025-09-12T09:58:57.389Z
Learning: gomesalexandre prefers letting errors throw and propagate up the call stack in form submit handlers rather than adding local try/catch error handling, consistent with his fail-fast approach in WalletConnect transaction confirmation flows.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-17T22:40:30.149Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10569
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/WalletConnectModalSigningFooter.tsx:121-129
Timestamp: 2025-09-17T22:40:30.149Z
Learning: gomesalexandre maintains strict scope discipline even for style/UI PRs in shapeshift/web, declining functionally correct UX improvements (like keeping Cancel button enabled during gas simulation loading) when they fall outside the PR's stated styling objectives, demonstrating his consistent pattern of deferring valid but tangential improvements to separate efforts.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-12T12:00:33.924Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/SendTransactionConfirmation.tsx:42-50
Timestamp: 2025-09-12T12:00:33.924Z
Learning: gomesalexandre prefers maintaining consistency with existing code patterns in WalletConnect modals, including side-effects-during-render for error handling (showErrorToast + handleReject), rather than introducing isolated refactors that would make the codebase inconsistent.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-08-14T17:56:23.721Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:545-566
Timestamp: 2025-08-14T17:56:23.721Z
Learning: gomesalexandre prefers not to extract helper functions for toast rendering patterns in TransactionRow.tsx (src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx), considering it over-abstraction even when there's code duplication between deposit and withdraw flows.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
📚 Learning: 2025-09-13T16:45:17.166Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/StructuredMessage/StructuredMessage.tsx:0-0
Timestamp: 2025-09-13T16:45:17.166Z
Learning: gomesalexandre appreciates safety-focused suggestions for UI rendering in WalletConnect components, specifically defensive programming approaches that prevent null/undefined values from displaying as literal "null"/"undefined" strings in the user interface.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-10-07T03:44:27.350Z
Learnt from: 0xApotheosis
Repo: shapeshift/web PR: 10760
File: src/components/ManageHiddenAssets/ManageHiddenAssetsList.tsx:78-84
Timestamp: 2025-10-07T03:44:27.350Z
Learning: In the ShapeShift web codebase, the following are stable references and do not need to be included in useCallback/useMemo dependency arrays:
- `navigate` from `useBrowserRouter()` hook
- Modal control objects (like `walletDrawer`) from `useModal()` hook (including their `isOpen`, `close`, and `open` methods)
- These are backed by stable context providers

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
📚 Learning: 2025-09-04T17:29:59.479Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10380
File: src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx:28-33
Timestamp: 2025-09-04T17:29:59.479Z
Learning: In shapeshift/web, the useGetPopularAssetsQuery function in src/components/TradeAssetSearch/hooks/useGetPopularAssetsQuery.tsx intentionally uses primaryAssets[assetId] instead of falling back to assets[assetId]. The design distributes primary assets across chains by iterating through their related assets and adding the primary asset to each related asset's chain. This ensures primary assets appear in all chains where they have related assets, supporting the grouped asset system.

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
  • packages/caip/src/adapters/coingecko/index.test.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Use `useAppDispatch` for Redux actions

Applied to files:

  • src/hooks/useActionCenterSubscribers/useSendActionSubscriber.tsx
📚 Learning: 2025-11-24T21:20:44.637Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/react-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:20:44.637Z
Learning: Applies to **/*.tsx : Ensure TypeScript types are explicit and proper; avoid use of `any` type

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Avoid 'any' types - use specific type annotations instead

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx} : Use strict typing - avoid `any`

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : NEVER use `any` type unless absolutely necessary in TypeScript

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use `unknown` instead of `any` when type is truly unknown in TypeScript

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use explicit types for function parameters and return values in TypeScript

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use explicit types for object shapes using interfaces or type aliases in TypeScript

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use descriptive property names in TypeScript type definitions

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:21:12.774Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/typescript-best-practices.mdc:0-0
Timestamp: 2025-11-24T21:21:12.774Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use type guards instead of type assertions when possible in TypeScript

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Log errors appropriately for debugging

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:17.804Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-11-24T21:20:17.804Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS log errors for debugging using structured logging with relevant context and error metadata

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-10-01T07:42:40.195Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10596
File: src/components/Layout/Header/NavBar/WalletConnectedMenu.tsx:77-99
Timestamp: 2025-10-01T07:42:40.195Z
Learning: In WalletConnectedMenu.tsx's handleReconnectWallet handler, gomesalexandre prefers throwing an error for unsupported wallet types in the default case rather than gracefully handling with a fallback. His reasoning: "if we have a problem here, we have bigger problems" - only supported wallets (KeepKey, Ledger, MetaMask, Coinbase, Phantom) should reach the reconnect flow when disconnected/locked, so encountering an unsupported type indicates a larger architectural issue that should be surfaced explicitly rather than masked with graceful degradation.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Don't silently catch and ignore exceptions

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:04.979Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T21:20:04.979Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Handle errors gracefully with meaningful messages

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:57.909Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/swapper.mdc:0-0
Timestamp: 2025-11-24T21:20:57.909Z
Learning: Applies to packages/swapper/src/swappers/**/*.ts : Validate inputs and log errors for debugging in Swapper system implementations

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:17.804Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-11-24T21:20:17.804Z
Learning: Applies to **/*.{tsx,jsx} : ALWAYS wrap React components in error boundaries and provide user-friendly fallback components with error logging

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-24T21:20:17.804Z
Learnt from: CR
Repo: shapeshift/web PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-11-24T21:20:17.804Z
Learning: Applies to **/*.{ts,tsx} : ALWAYS use custom error classes from `shapeshiftoss/errors` with meaningful error codes for internationalization and relevant details in error objects

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-12T11:56:19.437Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:0-0
Timestamp: 2025-09-12T11:56:19.437Z
Learning: gomesalexandre rejected verbose try/catch error handling for address validation in Tenderly integration (PR #10461), calling the approach "ugly" but still implemented safety measures in commit ad7e424b89, preferring cleaner safety implementations over defensive programming patterns.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-08-13T17:06:16.397Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10249
File: src/hooks/useActionCenterSubscribers/useThorchainLpWithdrawActionSubscriber.tsx:76-78
Timestamp: 2025-08-13T17:06:16.397Z
Learning: gomesalexandre prefers to keep error handling simple with console.error rather than implementing structured logging, especially when broader error handling patterns in the codebase (like THOR error handling) need systematic improvement rather than piecemeal fixes.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-12T13:16:27.004Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP712MessageDisplay.tsx:21-24
Timestamp: 2025-09-12T13:16:27.004Z
Learning: gomesalexandre declined to add error boundaries to WalletConnect modals in PR #10461, stating "no error boundaries in this pr ser", consistent with his preference to keep PR scope focused and defer tangential improvements to separate efforts.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-12T12:00:33.924Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/SendTransactionConfirmation.tsx:42-50
Timestamp: 2025-09-12T12:00:33.924Z
Learning: gomesalexandre prefers maintaining consistency with existing code patterns across WalletConnect modal components, including side-effects-during-render for error handling (showErrorToast + handleReject calls before return null), rather than introducing isolated refactors that would create inconsistency in the codebase.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-12T09:46:55.535Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:123-123
Timestamp: 2025-09-12T09:46:55.535Z
Learning: gomesalexandre prefers using `any` type for Tenderly API response parsing in WalletConnect flows (specifically for tupleItem parameters in parseDecodedInput), as the dynamic nature of external API responses makes strict typing less practical in this context.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-12T09:48:46.305Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/StructuredMessage/StructuredMessage.tsx:0-0
Timestamp: 2025-09-12T09:48:46.305Z
Learning: In WalletConnect signing flows dealing with structured message data (like StructuredField.value in StructuredMessage.tsx), gomesalexandre prefers using `any` type for values representing dynamic Solidity types from external API responses, consistent with their approach to other external API parsing in WalletConnect flows.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-10-16T11:14:40.657Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10783
File: src/context/ModalStackProvider/useModalRegistration.ts:30-41
Timestamp: 2025-10-16T11:14:40.657Z
Learning: gomesalexandre prefers to add lint rules (like typescript-eslint/strict-boolean-expressions for truthiness checks on numbers) to catch common issues project-wide rather than relying on code review to catch them.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-08-14T12:42:48.263Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10280
File: src/context/WalletProvider/MobileWallet/mobileMessageHandlers.ts:18-18
Timestamp: 2025-08-14T12:42:48.263Z
Learning: gomesalexandre prefers maintaining string literal patterns in the Message union type in src/context/WalletProvider/MobileWallet/mobileMessageHandlers.ts, even when there's some duplication between Command union and Message variants. They find properly typed string literals acceptable and prefer not to refactor for type hygiene in this context.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-08-13T17:07:10.763Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10249
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:447-503
Timestamp: 2025-08-13T17:07:10.763Z
Learning: gomesalexandre prefers relying on TypeScript's type system for validation rather than adding defensive runtime null checks when types are properly defined. They favor a TypeScript-first approach over defensive programming with runtime validations.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-08-11T09:45:51.174Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10219
File: src/components/MultiHopTrade/components/TradeInput/TradeInput.tsx:175-180
Timestamp: 2025-08-11T09:45:51.174Z
Learning: gomesalexandre prefers truthy checks over explicit boolean comparisons (e.g., `walletSupportsSellAssetChain` instead of `walletSupportsSellAssetChain === true`) when dealing with tri-state values (boolean | null) in TypeScript, as the falsy behavior for null/undefined is intentional and acceptable.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-12T12:04:59.556Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/content/SendTransactionContent.tsx:0-0
Timestamp: 2025-09-12T12:04:59.556Z
Learning: gomesalexandre confirmed that fromBaseUnit in the ShapeShift codebase correctly handles hex strings (like transaction.value from WalletConnect) without requiring manual hex-to-decimal conversion, as bnOrZero handles this automatically via BigNumber.js.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-07-28T10:36:26.897Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10121
File: src/hooks/useActionCenterSubscribers/useGenericTransactionSubscriber.tsx:65-66
Timestamp: 2025-07-28T10:36:26.897Z
Learning: In ShapeShift web app transaction processing, prefer parallel async execution over sequential processing to avoid blocking when handling multiple transactions. Use forEach for concurrent operations rather than for...of loops to prevent slower transactions from blocking faster ones.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-10-22T22:12:31.955Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10879
File: src/context/WalletProvider/WalletConnectV2/useDirectConnect.ts:15-23
Timestamp: 2025-10-22T22:12:31.955Z
Learning: In shapeshift/web WalletConnect V2 direct connection (src/context/WalletProvider/WalletConnectV2/useDirectConnect.ts), gomesalexandre prefers using native URL schemes only (metamask://, trust://, zerion://) and not universal links/app links for deep-linking.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-12T12:04:59.556Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/content/SendTransactionContent.tsx:0-0
Timestamp: 2025-09-12T12:04:59.556Z
Learning: The ShapeShift codebase's fromBaseUnit function correctly handles hex strings (like WalletConnect transaction.value) without manual conversion because bnOrZero -> bn -> new BigNumber() automatically detects and parses hex strings starting with "0x". gomesalexandre confirmed this with concrete evidence showing hex value 0x176d1c49189db correctly converts to 0.000412118294825435 ETH.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-11-25T21:43:10.838Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11170
File: patches/@shapeshiftoss+bitcoinjs-lib+7.0.0-shapeshift.0.patch:9-19
Timestamp: 2025-11-25T21:43:10.838Z
Learning: In shapeshift/web, gomesalexandre will not expand PR scope to fix latent bugs in unused API surface (like bitcoinjs-lib patch validation methods) when comprehensive testing proves the actual used code paths work correctly, preferring to avoid costly hdwallet/web verdaccio publish cycles and full regression testing for conceptual issues with zero runtime impact.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-08-08T15:00:22.321Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/components/MultiHopTrade/components/TradeInput/components/HighlightedTokens.tsx:14-14
Timestamp: 2025-08-08T15:00:22.321Z
Learning: In shapeshift/web reviews for NeOMakinG, avoid nitpicks to change deep-relative imports to '@/…' alias paths within feature/non-refactor PRs; defer such style-only changes to a dedicated follow-up refactor unless they fix an issue.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-09-12T09:58:50.671Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP155SignTypedDataConfirmation.tsx:14-15
Timestamp: 2025-09-12T09:58:50.671Z
Learning: In EIP155SignTypedDataConfirmation.tsx, gomesalexandre is comfortable with null returns for missing message data as TypeScript type safety guards, viewing them as compile-time protections rather than runtime scenarios that need explicit error handling and user feedback. He considers these TypeScript-level safeguards sufficient and prefers not to add defensive runtime error handling for what should be type-guaranteed scenarios.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
📚 Learning: 2025-08-08T15:00:49.887Z
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10231
File: src/components/AssetSearch/components/AssetList.tsx:2-2
Timestamp: 2025-08-08T15:00:49.887Z
Learning: Project shapeshift/web: NeOMakinG prefers avoiding minor a11y/UI nitpicks (e.g., adding aria-hidden to decorative icons in empty states like src/components/AssetSearch/components/AssetList.tsx) within feature PRs; defer such suggestions to a follow-up instead of blocking the PR.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
🧬 Code graph analysis (2)
src/components/MultiHopTrade/components/TradeConfirm/hooks/useTradeNetworkFeeCryptoBaseUnit.tsx (3)
packages/caip/src/constants.ts (1)
  • CHAIN_NAMESPACE (79-85)
src/lib/utils/tron.ts (1)
  • assertGetTronChainAdapter (18-27)
src/config.ts (1)
  • getConfig (224-226)
packages/caip/src/adapters/coingecko/index.test.ts (2)
packages/caip/src/assetId/assetId.ts (1)
  • toAssetId (59-127)
packages/caip/src/constants.ts (1)
  • CHAIN_NAMESPACE (79-85)
⏰ 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). (1)
  • GitHub Check: Install and Cache

@gomesalexandre gomesalexandre merged commit 0d17c37 into develop Nov 28, 2025
4 checks passed
@gomesalexandre gomesalexandre deleted the tron-support branch November 28, 2025 11:28
@coderabbitai coderabbitai bot mentioned this pull request Jan 22, 2026
1 task
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.

3 participants