Skip to content

fix: better tron estimates - #11274

Merged
NeOMakinG merged 24 commits into
developfrom
fix_tron_estimates
Dec 5, 2025
Merged

fix: better tron estimates#11274
NeOMakinG merged 24 commits into
developfrom
fix_tron_estimates

Conversation

@gomesalexandre

@gomesalexandre gomesalexandre commented Dec 3, 2025

Copy link
Copy Markdown
Contributor

Description

Handles TRC20 gas estimates better, severely underestimated atm and ending up doing at best, bandwidth errors at broadcast time, at worst, reverts and burned gas on-chain.

Issue (if applicable)

closes #11270

Risk

High Risk PRs Require 2 approvals

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

Low

Testing

  • TRX sends still happy and gas estimations are still happy
  • TRC20 sends now happy (with overestimation buffer) and insufficient gas detection is happy
  • Test both with well-TRX-funded (10+ TRX) or less (something like <=6 TRX) and ensure gas estimates are working somehow well for TRC-20 sends and blocking in case of too low TRX funding
  • Note, depending on whether the addy you're sending to has said TRC-20 or not, fees can almost double - make sure to test with that in mind too
  • Test you're still able to get TRON (TRX/TRC-20 quotes) for THOR and gas fees present, assuming wallet connected, and look somehow sane

Engineering

  • ^

Operations

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

Screenshots (if applicable)

  • Sends

https://jam.dev/c/9b2bad76-9d58-446b-9b5a-1c27edb9ad0c

  • THOR

https://jam.dev/c/bc1b1178-c43a-43ea-bbe7-d50469a55edc

Summary by CodeRabbit

  • New Features

    • Live Tron fee estimation using on-chain parameters, with memo-aware calculations.
    • Fee estimates now consider sender and contract context for TRC20 and TRX flows.
  • Bug Fixes

    • More accurate bandwidth and energy fee calculations, including TRC20 energy estimation with safety margin.
    • Updated fallback energy assumptions for more reliable predictions.

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

gomesalexandre and others added 17 commits December 3, 2025 01:04
- Add executeTronTransaction method to ThorchainSwapper for transaction execution
- Implement proper TRON fee estimation using real-time network prices:
  * TRC20: triggerConstantContract for energy calculation (~27 TRX)
  * TRX: actual bandwidth calculation with memo overhead (~0.3-0.5 TRX)
- Add VITE_TRON_NODE_URL to SwapperConfig
- Set networkFeeCryptoBaseUnit to undefined for rate quotes (calculated at execution time)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Reuse single TronWeb instance for transaction building
- Remove manual fee_limit restoration (addUpdateData preserves it)
- Clean up transaction flow

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…t address extraction

- Increase feeLimit to 150 TRX for TRC20 transfers with memo (covers energy + bandwidth)
- Use contractAddressOrUndefined utility consistently across tron utils
- Research shows feeLimit only covers energy, bandwidth is burned separately

Note: TRC20 transfers require ~64k-130k energy + ~345 bandwidth
With memo, bandwidth increases. Account needs TRX to burn for bandwidth if
free daily bandwidth (600 units) is exhausted.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Critical fix for TRC20 bandwidth error:
- Add txLocal: true to addUpdateData() call
- This preserves fee_limit field (150 TRX for TRC20 with memo)
- Without txLocal, addUpdateData calls wallet/getsignweight API which
  returns transaction WITHOUT fee_limit, causing "Account resource insufficient" error

Root cause: TronWeb's addUpdateData() loses fee_limit when using remote API.
Solution: txLocal: true forces local transaction recreation that preserves all fields.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…sues

Testing theory: txLocal: true might cause transaction validation issues.
Successful Thorchain TRC20 txs on-chain have both fee_limit and memo preserved,
suggesting addUpdateData() works correctly without txLocal option.

On-chain evidence:
- TX 78055EA7: fee_limit 100 TRX, has memo, SUCCESS
- TX BD77F95E: fee_limit 15.6 TRX, has memo, SUCCESS

If this doesn't work, need to investigate wallet balance or other issues.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
After analyzing SwapKit's TRON implementation and successful Thorchain TRC20 txs:
- Standard feeLimit is 100 TRX (not 150)
- addUpdateData() without txLocal is correct
- Transaction structure matches working implementations

Root cause of BANDWIDTH_ERROR confirmed:
- Account has 0.25 TRX liquid (frozen TRX cannot pay fees)
- Transaction needs ~7-8 TRX liquid for energy + memo fee
- Error is misleading - it's insufficient liquid TRX, not bandwidth

Code is correct. Issue is account balance.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Created TRON_FEE_ESTIMATION_ISSUES.md documenting critical problems:
- getFeeData() returns fixed 0.268 TRX for ALL transactions
- TRC20 transfers actually cost 6-15 TRX (24-56x underestimate)
- Causes misleading UI fees and on-chain transaction failures
- Users lose TRX in partial execution before OUT_OF_ENERGY errors

Added TODO comments in TronChainAdapter.getFeeData() with:
- Detect TRC20 vs TRX using contractAddress
- Use existing estimateTRC20TransferFee() method
- Account for memo overhead (1 TRX memo fee + bandwidth)
- Build actual transaction for accurate size estimation

Evidence includes failed txs and cost analysis.
Priority: HIGH - users losing funds on failed transactions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Created THORCHAIN_TRON_INTEGRATION.md covering:
- Architecture (UTXO-style pattern, not EVM)
- Implementation details for all components
- Memo handling via addUpdateData()
- Cost breakdown (energy, bandwidth, memo fee)
- Successful on-chain transaction examples
- Common issues and solutions
- Testing checklist
- Comparison with SwapKit implementation

Documents that implementation is correct and matches working integrations.
Main issue is inherited getFeeData() returning wrong fees for TRC20.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Fixed getTronTransactionFees to estimate from user's perspective:
- Use args.from instead of vault for triggerConstantContract issuerAddress
- Use args.from instead of vault for sendTrx from parameter
- Remove unnecessary Number() conversion (TronWeb accepts strings)

Why this matters:
- triggerConstantContract simulates execution from caller's perspective
- Using vault address estimated "vault→vault" cost, not "user→vault"
- Energy costs may vary based on sender's account state

Credit: coderabbitai review feedback

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
CodeRabbit was incorrect about sendTrx accepting strings.
TronWeb's TypeScript definition requires number for amount parameter:
  sendTrx(to: string, amount?: number, from?: string)

While implementation accepts strings internally, the type definition
enforces number, causing TS2345 error.

Kept the important fix: using args.from instead of vault for sender.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
More consistent with codebase patterns and safer for edge cases.
bnOrZero handles invalid inputs gracefully vs raw Number() cast.

Note: TronWeb's TypeScript definition requires number type for sendTrx amount,
so string is not an option (contrary to CodeRabbit's suggestion).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
CRITICAL: Fixes 24-50x fee underestimation causing OUT_OF_ENERGY failures

Previously returned fixed 0.268 TRX for all transactions.
Now returns accurate estimates validated against real transactions:
- TRC20 transfers: 6.7-13.3 TRX (without memo)
- TRC20 with memo: 7.8-14.4 TRX
- TRX transfers: 0.198 TRX (without memo)
- TRX with memo: 1.231 TRX

Validation Results (Real Thorchain USDT swaps + User transaction):
- User tx: 6.77 TRX actual, 9.92 TRX estimated (1.46x = conservative ✅)
- Thor tx 1: 7.84 TRX actual, 10.92 TRX estimated (1.39x = conservative ✅)
- Thor tx 2: 7.82 TRX actual, 10.92 TRX estimated (1.40x = conservative ✅)
- Old estimate: 0.268 TRX (0.034x actual = 29x underestimate ❌)
- Improvement: 41x more accurate

Implementation:
- Detects TRC20 vs TRX via contractAddress in chainSpecific
- Calls estimateTRC20TransferFee() with actual recipient address
- Applies 1.5x safety margin for dynamic energy spikes (max 3.4x)
- Builds real transactions to measure bandwidth accurately
- Adds 1 TRX memo fee when present (network parameter #68)
- Thor/TRON rates now show fees when wallet connected
- Send modal now passes contractAddress for TRC20 detection

Files Modified:
- TronChainAdapter.ts: Rewritten getFeeData() (85 lines)
- getL1RateOrQuote.ts: Thor rates with fee calculation (68 lines)
- api.ts: Realistic fallback (31→13 TRX)
- tron/types.ts: Added GetFeeDataInput type
- types.ts: Added TRON to ChainSpecificGetFeeDataInput
- Send/utils.ts: Pass contractAddress and memo to getFeeData
- NearIntentsSwapper: Added chainSpecific for TRON calls

Technical Details:
- Uses triggerConstantContract (estimateEnergy not available on TronGrid)
- SSTORE cost varies 2x based on recipient balance (20k vs 5k energy)
- Dynamic energy can spike up to 3.4x during congestion
- Memo fee confirmed via getChainParameters(): 1,000,000 SUN
- Energy price: 100 SUN/unit (mainnet), 210 SUN/unit (Shasta)
- Validated against NETTS article: 65k/131k energy for USDT

Fixes #11270

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The 19.776 TRX estimate was caused by using fallback (130k energy)
because triggerConstantContract didn't have a valid sender address.

Changes:
- Added 'from' (sender) to TRON GetFeeDataInput type
- Send modal now extracts and passes sender address from accountId
- estimateTRC20TransferFee uses actual sender for accurate estimation

This fixes the recipient balance detection:
- Recipient HAS USDT: ~64k energy → 9.6 TRX estimate
- Recipient NO USDT: ~130k energy → 19.5 TRX estimate

Previously always used fallback 130k energy (19.5 TRX) because
sender address was missing. Now estimates accurately based on
actual sender calling triggerConstantContract.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Added user-facing documentation explaining TRON fee structure:
- Why USDT transfers cost $1-3 (normal and expected)
- How energy and bandwidth fees work
- Real transaction examples with breakdowns
- Dynamic energy model explanation
- Fee reduction strategies
- Links to TRON docs, explorers, and resources

This helps users understand why fees changed from $0.05 to $2
(the old $0.05 was a bug, $1-2 is the real cost).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@gomesalexandre
gomesalexandre requested a review from a team as a code owner December 3, 2025 11:32
@gomesalexandre
gomesalexandre changed the base branch from develop to feat_thor_tron December 3, 2025 11:33
@coderabbitai

coderabbitai Bot commented Dec 3, 2025

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Refactors TRON fee estimation to use live chain parameters and transaction-specific inputs. Adds a new GetFeeDataInput type and threads from/contractAddress/memo through callers to compute energy, bandwidth, and memo fees for TRC20 and TRX transfers.

Changes

Cohort / File(s) Summary
Core TRON adapter
packages/chain-adapters/src/tron/TronChainAdapter.ts, packages/chain-adapters/src/tron/types.ts
Reworked getFeeData signature to accept GetFeeDataInput (from?, contractAddress?, memo?) and compute fees dynamically using TronWeb chain parameters, estimateTRC20TransferFee, bandwidth estimation, 1.5× safety margin for energy, and memo handling. Returns fast/average/slow txFee strings and observed bandwidth.
Public type mapping
packages/chain-adapters/src/types.ts
Added tron.GetFeeDataInput mapping for KnownChainIds.TronMainnet in ChainSpecificGetFeeDataInput<T>.
Unchained client (TRON)
packages/unchained-client/src/tron/api.ts
Changed estimateTRC20TransferFee fallback from 31000000 to 13000000 (documented as 130k energy assumption / ~13 TRX).
Swapper integrations
packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts, packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts, packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts, packages/swapper/src/swappers/SunioSwapper/utils/getQuoteOrRate.ts
Threaded explicit chainSpecific into Tron fee queries (often {} or with from/contractAddress), added Tron-specific async fee estimation in getL1RateOrQuote to compute networkFeeCryptoBaseUnit for rate quotes when receiveAddress exists.
Send flow / UI hooks
src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx, src/components/Modals/Send/utils.ts, src/hooks/queries/useApprovalFees.ts
Derive and pass from via fromAccountId, include chainSpecific with from/contractAddress/memo into estimateFees and approval fee estimations; changed approval fee target to use to: spender with chainSpecific containing contract address.
Minor callsite adjustments
packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts (imports), packages/swapper/src/swappers/SunioSwapper/utils/getQuoteOrRate.ts
Added imports (TronWeb, contractAddressOrUndefined), changed fee target for SUNIO router to use contract-level call and pass from/contractAddress.

Sequence Diagram(s)

sequenceDiagram
    participant UI as UI (Send / Swapper)
    participant Adapter as TronChainAdapter
    participant Web as TronWeb
    participant Unchained as Unchained Client
    participant Chain as TRON Chain

    UI->>Adapter: getFeeData({to, value, chainSpecific:{from?, contractAddress?, memo?}})
    Adapter->>Web: instantiate TronWeb & getChainParameters()
    Web->>Chain: getChainParameters()
    Chain-->>Web: bandwidthPrice, energyPrice
    Web-->>Adapter: prices

    alt contractAddress present (TRC20)
        Adapter->>Unchained: estimateTRC20TransferFee(contractAddress, from?, to?)
        Unchained->>Chain: simulate/estimate energyUsed
        Chain-->>Unchained: energyUsed
        Unchained-->>Adapter: energyUsed
        Adapter->>Adapter: energyFee = energyUsed × energyPrice × 1.5
        Adapter->>Adapter: bandwidthFee = fixedBytes (≈276) × bandwidthPrice
    else TRX transfer (no contractAddress)
        Adapter->>Web: build transaction (include memo if present) to estimate size
        Web->>Chain: estimate transaction size / bandwidth
        Chain-->>Web: totalBytes
        Web-->>Adapter: bandwidthFee = totalBytes × bandwidthPrice
        Adapter->>Adapter: energyFee = 0
    end

    alt memo present
        Adapter->>Adapter: memoFee = 1 TRX (added to total)
    end

    Adapter->>Adapter: totalFee = energyFee + bandwidthFee + memoFee
    Adapter-->>UI: FeeDataEstimate {fast/average/slow strings, observed bandwidth}
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay attention to packages/chain-adapters/src/tron/TronChainAdapter.ts (branching TRC20 vs TRX logic, safety margins, memo handling).
  • Review packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts async mapping and fallback/error behavior.
  • Confirm GetFeeDataInput propagation and usage across callers (send flow, swappers, approval fees).
  • Verify the unchained-client fallback change (13000000 SUN) aligns with expectations.

Possibly related PRs

Suggested reviewers

  • NeOMakinG

Poem

🐰 Soft paws on Tron I hop and hum,

Fees once tiny now counted by thumb.
Energy, bandwidth, memo in tune—
Transactions hum under a fuller moon. ✨

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 (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: better tron estimates' accurately reflects the main objective of implementing improved TRON fee estimation logic to address the 24-48x underestimation issue for TRC20 transfers.
Linked Issues check ✅ Passed The PR successfully implements all required objectives from issue #11270: detects TRC20 vs TRX transfers via contractAddress, uses dynamic chain parameters for pricing, integrates energy/bandwidth estimation methods, builds actual transactions for accurate costs, and adds memo fee handling.
Out of Scope Changes check ✅ Passed All code changes directly support the core objective of improving TRON fee estimation. Type additions, adapter updates, and integration points across swappers and UI components are all aligned with detecting and accurately estimating TRC20 vs TRX transfer costs.
✨ 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 fix_tron_estimates

📜 Recent 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 6b1e3ba and ae4f809.

📒 Files selected for processing (4)
  • packages/chain-adapters/src/tron/TronChainAdapter.ts (1 hunks)
  • packages/swapper/src/swappers/SunioSwapper/utils/getQuoteOrRate.ts (2 hunks)
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts (4 hunks)
  • src/hooks/queries/useApprovalFees.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{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/SunioSwapper/utils/getQuoteOrRate.ts
  • packages/chain-adapters/src/tron/TronChainAdapter.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
  • src/hooks/queries/useApprovalFees.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/SunioSwapper/utils/getQuoteOrRate.ts
  • packages/chain-adapters/src/tron/TronChainAdapter.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
  • src/hooks/queries/useApprovalFees.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/SunioSwapper/utils/getQuoteOrRate.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.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/SunioSwapper/utils/getQuoteOrRate.ts
  • packages/chain-adapters/src/tron/TronChainAdapter.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
  • src/hooks/queries/useApprovalFees.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/SunioSwapper/utils/getQuoteOrRate.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.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/SunioSwapper/utils/getQuoteOrRate.ts
🧠 Learnings (26)
📓 Common learnings
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11261
File: src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx:117-172
Timestamp: 2025-12-03T23:16:28.342Z
Learning: In TRON transaction confirmation polling (e.g., approval flows in useAllowanceApproval.tsx), gomesalexandre is comfortable with optimistic completion when polling times out after the configured duration (e.g., 60 seconds). He considers the timeout a "paranoia" safety net for unlikely scenarios, expecting normal transactions to complete much faster. He prefers to defer more sophisticated timeout/failure handling as a separate follow-up concern rather than expanding PR scope.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10810
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:212-0
Timestamp: 2025-10-15T15:57:39.956Z
Learning: gomesalexandre uses discriminated union patterns (e.g., `isEIP1559 ? { max_fee_per_gas, max_priority_fee_per_gas } : { gas_price }`) in WalletConnect flows without additional validation guards, trusting that the runtime data structure ensures mutual exclusivity between EIP-1559 and legacy gas pricing fields.
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.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11261
File: src/lib/utils/tron/getAllowance.ts:14-59
Timestamp: 2025-12-03T23:21:16.985Z
Learning: In src/lib/utils/tron/getAllowance.ts, gomesalexandre is not concerned about adding comprehensive error handling (try-catch blocks, custom error classes) for the getTrc20Allowance utility function, because it is used close to the view layer. He prefers simpler error handling for view-layer utilities, letting errors propagate naturally rather than adding defensive guards.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/EIP155RequestHandlerUtil.ts:94-103
Timestamp: 2025-09-12T13:43:19.770Z
Learning: gomesalexandre has implemented a reliable gasLimit flow in WalletConnect dApps where Tenderly simulation provides gas estimates that get written to the form via setValue in GasSelectionMenu.tsx, making customTransactionData.gasLimit the primary reliable source. The sendTransaction.gasLimit fallback is kept as "paranoia" but may rarely be hit in practice due to this simulation-based architecture.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/EIP155RequestHandlerUtil.ts:94-103
Timestamp: 2025-09-12T13:43:19.770Z
Learning: gomesalexandre has implemented a sophisticated gasLimit management system in WalletConnect dApps using Tenderly simulation. The GasSelectionMenu component automatically adjusts gasLimit via setValue when simulation shows higher gas usage than currently set, handling edge cases like dApps that enforce low gas limits (e.g., 21000) when actual usage is higher (e.g., 23322). This makes customTransactionData.gasLimit highly reliable as the primary source.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx:0-0
Timestamp: 2025-09-13T16:45:18.813Z
Learning: gomesalexandre prefers aggressively deleting unused/obsolete code files ("ramboing") rather than fixing technical issues in code that won't be used, demonstrating his preference for keeping codebases clean and PR scope focused.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/types.ts:7-7
Timestamp: 2025-09-10T15:34:29.604Z
Learning: gomesalexandre is comfortable relying on transitive dependencies (like abitype through ethers/viem) rather than explicitly declaring them in package.json, preferring to avoid package.json bloat when the transitive dependency approach works reliably in practice.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10503
File: .env:56-56
Timestamp: 2025-09-16T13:17:02.938Z
Learning: gomesalexandre prefers to enable feature flags globally in the base .env file when the intent is to activate features everywhere, even when there are known issues like crashes, demonstrating his preference for intentional global feature rollouts over cautious per-environment enablement.
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.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.
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.
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.
📚 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/swappers/SunioSwapper/utils/getQuoteOrRate.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.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/SunioSwapper/utils/getQuoteOrRate.ts
  • src/hooks/queries/useApprovalFees.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/SunioSwapper/utils/getQuoteOrRate.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/SunioSwapper/utils/getQuoteOrRate.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.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/SunioSwapper/utils/getQuoteOrRate.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.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/SunioSwapper/utils/getQuoteOrRate.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
  • src/hooks/queries/useApprovalFees.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/swappers/SunioSwapper/utils/getQuoteOrRate.ts
📚 Learning: 2025-12-04T11:05:01.112Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11281
File: packages/swapper/src/swappers/PortalsSwapper/utils/fetchSquidStatus.ts:98-106
Timestamp: 2025-12-04T11:05:01.112Z
Learning: In packages/swapper/src/swappers/PortalsSwapper/utils/fetchSquidStatus.ts, getSquidTrackingLink should return blockchain explorer links (using Asset.explorerTxLink) rather than API endpoints. For non-GMP Squid swaps: return source chain explorer link with sourceTxHash when pending/failed, and destination chain explorer link with destinationTxHash when confirmed.

Applied to files:

  • packages/swapper/src/swappers/SunioSwapper/utils/getQuoteOrRate.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/SunioSwapper/utils/getQuoteOrRate.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
📚 Learning: 2025-12-01T22:01:37.982Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11240
File: packages/swapper/src/swappers/CetusSwapper/endpoints.ts:56-58
Timestamp: 2025-12-01T22:01:37.982Z
Learning: In packages/swapper/src/swappers/CetusSwapper/endpoints.ts, gomesalexandre is comfortable with mutating the shared Cetus SDK singleton instance (sdk.senderAddress = from) when required by the SDK API, preferring pragmatic working code over theoretical statelessness concerns.

Applied to files:

  • packages/swapper/src/swappers/SunioSwapper/utils/getQuoteOrRate.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/SunioSwapper/utils/getQuoteOrRate.ts
📚 Learning: 2025-08-05T23:36:13.214Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10187
File: src/state/slices/preferencesSlice/selectors.ts:21-25
Timestamp: 2025-08-05T23:36:13.214Z
Learning: The AssetId type from 'shapeshiftoss/caip' package is a string type alias, so it can be used directly as a return type for cache key resolvers in re-reselect selectors without needing explicit string conversion.

Applied to files:

  • packages/swapper/src/swappers/SunioSwapper/utils/getQuoteOrRate.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/SunioSwapper/utils/getQuoteOrRate.ts
📚 Learning: 2025-09-12T10:21:26.693Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP712MessageDisplay.tsx:0-0
Timestamp: 2025-09-12T10:21:26.693Z
Learning: gomesalexandre explained that in WalletConnect V2, the request context chainId comes from params?.chainId following CAIP2 standards, making both the request params chainId and EIP-712 domain chainId equally reliable sources. He considers both approaches trustworthy ("both gucci") for WalletConnect dApps integration.

Applied to files:

  • packages/swapper/src/swappers/SunioSwapper/utils/getQuoteOrRate.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/swapper/src/thorchain-utils/getL1RateOrQuote.ts
📚 Learning: 2025-08-05T16:39:58.598Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10191
File: src/pages/Explore/Explore.tsx:56-56
Timestamp: 2025-08-05T16:39:58.598Z
Learning: In the ShapeShift web codebase, the established pattern for handling floating point numbers is to use BigNumber operations (bnOrZero, bn) for calculations and convert to strings using .toString() before passing to UI components like Amount.Fiat, Amount.Crypto, and Amount.Percent. This prevents JavaScript floating point precision issues and maintains consistency across the application.

Applied to files:

  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.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/swapper/src/thorchain-utils/getL1RateOrQuote.ts
📚 Learning: 2025-07-24T11:07:20.536Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10073
File: src/features/defi/providers/fox-farming/components/FoxFarmingManager/Claim/Claim.tsx:77-84
Timestamp: 2025-07-24T11:07:20.536Z
Learning: In fox farming components, the `opportunity?.rewardsCryptoBaseUnit?.amounts` property has a well-defined type signature that is always an array (never undefined), but can be empty: `readonly [] | readonly [string, string, string] | readonly [string, string] | readonly [string]`. Using optional chaining on the `amounts` property itself is unnecessary since it's always defined, though accessing `amounts[0]` on an empty array returns undefined which bnOrZero() handles safely.

Applied to files:

  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
📚 Learning: 2025-11-18T09:52:51.368Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10334
File: src/lib/user/api.ts:46-105
Timestamp: 2025-11-18T09:52:51.368Z
Learning: In the shapeshift/web repository, monadic error-handling with Result types (Ok/Err from sniptt/monads) is specific to the swapper domain and is not used anywhere else in the codebase. API helpers outside the swapper domain (e.g., user API, notification services) should use traditional throw/catch error handling patterns instead of Result monads.

Applied to files:

  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.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} : 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

Applied to files:

  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.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/thorchain-utils/getL1RateOrQuote.ts
📚 Learning: 2025-12-03T23:21:16.985Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11261
File: src/lib/utils/tron/getAllowance.ts:14-59
Timestamp: 2025-12-03T23:21:16.985Z
Learning: In src/lib/utils/tron/getAllowance.ts, gomesalexandre is not concerned about adding comprehensive error handling (try-catch blocks, custom error classes) for the getTrc20Allowance utility function, because it is used close to the view layer. He prefers simpler error handling for view-layer utilities, letting errors propagate naturally rather than adding defensive guards.

Applied to files:

  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.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/thorchain-utils/getL1RateOrQuote.ts
📚 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:

  • src/hooks/queries/useApprovalFees.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:

  • src/hooks/queries/useApprovalFees.ts
🧬 Code graph analysis (3)
packages/swapper/src/swappers/SunioSwapper/utils/getQuoteOrRate.ts (2)
packages/swapper/src/swappers/SunioSwapper/utils/constants.ts (1)
  • SUNIO_SMART_ROUTER_CONTRACT (12-12)
packages/utils/src/index.ts (1)
  • contractAddressOrUndefined (46-47)
packages/chain-adapters/src/tron/TronChainAdapter.ts (2)
packages/chain-adapters/src/tron/types.ts (1)
  • GetFeeDataInput (24-28)
packages/chain-adapters/src/types.ts (2)
  • GetFeeDataInput (326-333)
  • FeeDataEstimate (107-111)
packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts (2)
packages/utils/src/index.ts (1)
  • contractAddressOrUndefined (46-47)
packages/utils/src/assetData/baseAssets.ts (1)
  • tron (339-353)
⏰ 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: Call / Static
🔇 Additional comments (3)
packages/swapper/src/swappers/SunioSwapper/utils/getQuoteOrRate.ts (1)

2-2: LGTM! Correct implementation of TRC20-aware fee estimation.

The changes correctly implement the fee estimation improvements per the PR objectives:

  • Router-targeted estimation (line 121): to: SUNIO_SMART_ROUTER_CONTRACT correctly targets the actual transaction destination for Sunio swaps, rather than the receive address.

  • TRC20 detection (line 126): contractAddress: contractAddressOrUndefined(sellAsset.assetId) enables the adapter to distinguish TRC20 token transfers (contract address present) from native TRX transfers (undefined), addressing the 24-48x fee underestimation issue.

  • Sender context (line 125): from: receiveAddress provides the sender address needed for accurate bandwidth/energy cost calculation based on the user's available resources.

This properly addresses the root cause described in the PR objectives where getFeeData() was ignoring inputs and returning fixed estimates regardless of transaction type.

Also applies to: 121-127

src/hooks/queries/useApprovalFees.ts (1)

60-87: TRON approval fee input wiring looks correct

Passing to: spender with chainSpecific: { from, contractAddress: to } matches the new Tron getFeeData input shape and correctly distinguishes the TRC20 contract (asset reference) from the spender. Using value: '0' for approval energy estimation is also reasonable since gas is amount‑independent.

packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts (1)

8-9: Using route.quote.memo for Tron bandwidth estimation is correct; memo variable is empty for rate requests

The current implementation correctly uses route.quote.memo for the TRX bandwidth calculation. The memo variable from getMemo(route) returns an empty string for rate requests (line 161), while fee estimation only occurs for rate requests with a connected wallet (line 450). Using the processed memo would zero out the memo byte calculation, resulting in inaccurate fee estimates. The route.quote.memo value represents the actual memo that would be included in the transaction and is the appropriate value for bandwidth estimation at this stage.

Likely an incorrect or invalid review comment.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • TRC-20: Entity not found: Issue - Could not find referenced Issue.

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.

@gomesalexandre
gomesalexandre marked this pull request as draft December 3, 2025 11:35
@gomesalexandre gomesalexandre mentioned this pull request Dec 3, 2025
1 task
- Remove documentation files (not needed in codebase)
- Remove console.warn from getL1RateOrQuote.ts
- Keep only essential code changes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@gomesalexandre
gomesalexandre marked this pull request as ready for review December 3, 2025 23:12
gomesalexandre and others added 3 commits December 4, 2025 02:14
- Remove debug console.log with fee estimation info
- Remove console.debug in error catch block

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Base automatically changed from feat_thor_tron to develop December 4, 2025 16:05
Resolve merge conflicts after PR #11266 was squash merged. The original
PR had basic/placeholder Tron fee estimation, while this branch contains
the improved fee estimation logic. Kept the improvements from HEAD.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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)
packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts (1)

220-229: Pass from address in Tron chainSpecific for consistent and accurate TRC20 fee estimation.

The Tron case passes an empty chainSpecific object, while the EVM, Solana, and Sui cases all pass from in chainSpecific. The Tron adapter uses the from address to improve TRC20 energy estimation via estimateTRC20TransferFee—when from is not provided, it falls back to using the recipient address. Pass from: from in the chainSpecific object to maintain consistency and enable accurate fee calculation.

🧹 Nitpick comments (5)
packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts (2)

484-489: Consider extracting magic numbers to constants.

The fee calculation uses several hardcoded values that would benefit from being defined as named constants for maintainability and clarity.

Extract these values to constants at the file or module level:

const TRON_ENERGY_SAFETY_MARGIN = 1.5
const TRON_TRC20_BANDWIDTH_BYTES = 276
const TRON_BASE_BANDWIDTH_BYTES = 198
const TRON_FALLBACK_FEE_SUN = 13_000_000 // 13 TRX worst case

Then use them in the calculation:

-                 const energyFee = energyUsed * energyPrice * 1.5 // 1.5x safety margin
-                 const bandwidthFee = 276 * bandwidthPrice // TRC20 bandwidth
+                 const energyFee = energyUsed * energyPrice * TRON_ENERGY_SAFETY_MARGIN
+                 const bandwidthFee = TRON_TRC20_BANDWIDTH_BYTES * bandwidthPrice
                  totalFee = Math.ceil(energyFee + bandwidthFee)
                } catch {
                  // Fallback: Conservative estimate
-                 totalFee = 13_000_000 // 13 TRX worst case
+                 totalFee = TRON_FALLBACK_FEE_SUN
                }

This improves code clarity and makes it easier to tune these values based on real-world data.


462-462: Optional: Consider reusing TronWeb instance across routes.

A new TronWeb instance is created for each route iteration, which could be optimized by creating a single instance before the map.

+     const tronWeb = new TronWeb({ fullHost: deps.config.VITE_TRON_NODE_URL })
+     const params = await tronWeb.trx.getChainParameters()
+     const bandwidthPrice = params.find(p => p.key === 'getTransactionFee')?.value ?? 1000
+     const energyPrice = params.find(p => p.key === 'getEnergyFee')?.value ?? 100
+
      const maybeRoutes = await Promise.allSettled(
        perRouteValues.map(async (route): Promise<T> => {
          const memo = getMemo(route)
          let networkFeeCryptoBaseUnit: string | undefined = undefined

          if (input.quoteOrRate === 'rate' && input.receiveAddress) {
            try {
-             const tronWeb = new TronWeb({ fullHost: deps.config.VITE_TRON_NODE_URL })
-             const params = await tronWeb.trx.getChainParameters()
-             const bandwidthPrice = params.find(p => p.key === 'getTransactionFee')?.value ?? 1000
-             const energyPrice = params.find(p => p.key === 'getEnergyFee')?.value ?? 100

This reduces redundant initialization and network calls when processing multiple routes.

packages/chain-adapters/src/tron/TronChainAdapter.ts (3)

364-377: getFeeData input handling and chain parameter lookup look good; consider reusing TronWeb instance

The refactor to use GetFeeDataInput<KnownChainIds.TronMainnet> and destructure chainSpecific for { from, contractAddress, memo } is clear and aligns with the new type surface. The getChainParameters() call is also a reasonable way to derive bandwidthPrice and energyPrice.

One optional improvement: TronWeb is instantiated here and also in buildSendApiTransaction. You could move this to a single adapter-level instance (e.g., a private getter or field initialized in the constructor) so both methods share it and you avoid repeating the setup and potential configuration drift. Caching getChainParameters() for a short period (e.g., per process or per minute) could also be a future optimization if this path becomes hot.


378-399: Clarify estimateTRC20TransferFee units and consider deriving memo fee from chain parameters

The TRC20 path and memo handling look directionally correct and should eliminate the previous underestimation, but there are a couple of assumptions worth double‑checking:

  1. estimateTRC20TransferFee return units

    You treat energyEstimate as a fee in SUN (energyFee = Number(energyEstimate)), while the fallback path computes 130000 * energyPrice (energy units × price). This is fine if estimateTRC20TransferFee already returns a fee (not raw energy units), but it would under‑estimate if it instead returns just energy usage. Please confirm the exact return units of estimateTRC20TransferFee and, if it returns energy units, multiply by energyPrice before applying the 1.5x margin to keep units consistent with the fallback and with bandwidthFee.

  2. Memo fee source

    memoFee is hardcoded to 1_000_000 SUN with a comment referencing network parameter #68. Since you already have params from getChainParameters(), you could optionally read memoFee directly from there (with a sane default) to automatically track future parameter changes:

    - // Add 1 TRX memo fee when memo present (network parameter #68)
    - const memoFee = memo ? 1_000_000 : 0
    + const memoParam = params.find(p => p.key === 'memoFee')?.value ?? 1_000_000
    + const memoFee = memo ? memoParam : 0

    This keeps the adapter aligned with live chain config without needing manual updates.

  3. Single fee tier across fast/average/slow

    Returning the same txFee for fast, average, and slow is acceptable on Tron since there’s no gas‑price market, but just confirm this matches the UI expectations for fee tiering.

Also applies to: 427-434, 437-447


401-425: Use from ?? to as the sender when building TRX estimation transaction

In the TRX branch, sendTrx is called with the recipient address as both to and from:

const baseTx = await tronWeb.transactionBuilder.sendTrx(
  to,
  Number(value),
  to, // Use recipient as sender for estimation
)

For pure size estimation this is probably fine, but when from is available in chainSpecific you can make the estimation closer to the real transaction and avoid surprises by using it:

- const baseTx = await tronWeb.transactionBuilder.sendTrx(
-   to,
-   Number(value),
-   to, // Use recipient as sender for estimation
- )
+ const estimationFrom = from ?? to
+ const baseTx = await tronWeb.transactionBuilder.sendTrx(
+   to,
+   Number(value),
+   estimationFrom,
+ )

This keeps the estimation structurally aligned with the actual transaction while preserving a safe fallback when from is not provided.

📜 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 ac0fb48 and 6b1e3ba.

📒 Files selected for processing (9)
  • packages/chain-adapters/src/tron/TronChainAdapter.ts (1 hunks)
  • packages/chain-adapters/src/tron/types.ts (1 hunks)
  • packages/chain-adapters/src/types.ts (1 hunks)
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts (1 hunks)
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts (1 hunks)
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts (4 hunks)
  • packages/unchained-client/src/tron/api.ts (1 hunks)
  • src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx (2 hunks)
  • src/components/Modals/Send/utils.ts (1 hunks)
🧰 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/chain-adapters/src/types.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/chain-adapters/src/tron/types.ts
  • packages/chain-adapters/src/tron/TronChainAdapter.ts
  • src/components/Modals/Send/utils.ts
  • src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx
  • packages/unchained-client/src/tron/api.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.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/chain-adapters/src/types.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/chain-adapters/src/tron/types.ts
  • packages/chain-adapters/src/tron/TronChainAdapter.ts
  • src/components/Modals/Send/utils.ts
  • src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx
  • packages/unchained-client/src/tron/api.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.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/chain-adapters/src/types.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/chain-adapters/src/tron/types.ts
  • packages/chain-adapters/src/tron/TronChainAdapter.ts
  • src/components/Modals/Send/utils.ts
  • src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx
  • packages/unchained-client/src/tron/api.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.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/swapperApi/getTradeQuote.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.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/swapperApi/getTradeQuote.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.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/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.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/Modals/Send/hooks/useSendDetails/useSendDetails.tsx
**/*.{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/Modals/Send/hooks/useSendDetails/useSendDetails.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/Modals/Send/hooks/useSendDetails/useSendDetails.tsx
🧠 Learnings (28)
📓 Common learnings
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11261
File: src/components/MultiHopTrade/components/TradeConfirm/hooks/useAllowanceApproval.tsx:117-172
Timestamp: 2025-12-03T23:16:28.342Z
Learning: In TRON transaction confirmation polling (e.g., approval flows in useAllowanceApproval.tsx), gomesalexandre is comfortable with optimistic completion when polling times out after the configured duration (e.g., 60 seconds). He considers the timeout a "paranoia" safety net for unlikely scenarios, expecting normal transactions to complete much faster. He prefers to defer more sophisticated timeout/failure handling as a separate follow-up concern rather than expanding PR scope.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10810
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:212-0
Timestamp: 2025-10-15T15:57:39.956Z
Learning: gomesalexandre uses discriminated union patterns (e.g., `isEIP1559 ? { max_fee_per_gas, max_priority_fee_per_gas } : { gas_price }`) in WalletConnect flows without additional validation guards, trusting that the runtime data structure ensures mutual exclusivity between EIP-1559 and legacy gas pricing fields.
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.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11261
File: src/lib/utils/tron/getAllowance.ts:14-59
Timestamp: 2025-12-03T23:21:16.985Z
Learning: In src/lib/utils/tron/getAllowance.ts, gomesalexandre is not concerned about adding comprehensive error handling (try-catch blocks, custom error classes) for the getTrc20Allowance utility function, because it is used close to the view layer. He prefers simpler error handling for view-layer utilities, letting errors propagate naturally rather than adding defensive guards.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/EIP155RequestHandlerUtil.ts:94-103
Timestamp: 2025-09-12T13:43:19.770Z
Learning: gomesalexandre has implemented a reliable gasLimit flow in WalletConnect dApps where Tenderly simulation provides gas estimates that get written to the form via setValue in GasSelectionMenu.tsx, making customTransactionData.gasLimit the primary reliable source. The sendTransaction.gasLimit fallback is kept as "paranoia" but may rarely be hit in practice due to this simulation-based architecture.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/EIP155RequestHandlerUtil.ts:94-103
Timestamp: 2025-09-12T13:43:19.770Z
Learning: gomesalexandre has implemented a sophisticated gasLimit management system in WalletConnect dApps using Tenderly simulation. The GasSelectionMenu component automatically adjusts gasLimit via setValue when simulation shows higher gas usage than currently set, handling edge cases like dApps that enforce low gas limits (e.g., 21000) when actual usage is higher (e.g., 23322). This makes customTransactionData.gasLimit highly reliable as the primary source.
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.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10206
File: src/config.ts:127-128
Timestamp: 2025-08-07T11:20:44.614Z
Learning: gomesalexandre prefers required environment variables without default values in the config file (src/config.ts). They want explicit configuration and fail-fast behavior when environment variables are missing, rather than having fallback defaults.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/ContractInteractionBreakdown.tsx:0-0
Timestamp: 2025-09-13T16:45:18.813Z
Learning: gomesalexandre prefers aggressively deleting unused/obsolete code files ("ramboing") rather than fixing technical issues in code that won't be used, demonstrating his preference for keeping codebases clean and PR scope focused.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/types.ts:7-7
Timestamp: 2025-09-10T15:34:29.604Z
Learning: gomesalexandre is comfortable relying on transitive dependencies (like abitype through ethers/viem) rather than explicitly declaring them in package.json, preferring to avoid package.json bloat when the transitive dependency approach works reliably in practice.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10503
File: .env:56-56
Timestamp: 2025-09-16T13:17:02.938Z
Learning: gomesalexandre prefers to enable feature flags globally in the base .env file when the intent is to activate features everywhere, even when there are known issues like crashes, demonstrating his preference for intentional global feature rollouts over cautious per-environment enablement.
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.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/hooks/useActionCenterSubscribers/useThorchainLpDepositActionSubscriber.tsx:61-66
Timestamp: 2025-08-14T17:51:47.556Z
Learning: gomesalexandre is not concerned about structured logging and prefers to keep console.error usage as-is rather than implementing structured logging patterns, even when project guidelines suggest otherwise.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10413
File: src/components/Modals/FiatRamps/fiatRampProviders/onramper/utils.ts:29-55
Timestamp: 2025-09-02T14:26:19.028Z
Learning: gomesalexandre prefers to keep preparatory/reference code simple until it's actively consumed, rather than implementing comprehensive error handling, validation, and robustness improvements upfront. They prefer to add these improvements when the code is actually being used in production.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10276
File: src/pages/ThorChainLP/components/ReusableLpStatus/TransactionRow.tsx:396-402
Timestamp: 2025-08-14T17:55:57.490Z
Learning: gomesalexandre is comfortable with functions/variables that return undefined or true (tri-state) when only the truthy case matters, preferring to rely on JavaScript's truthy/falsy behavior rather than explicitly returning boolean values.
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.
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.
📚 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/chain-adapters/src/types.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/chain-adapters/src/tron/types.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.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/chain-adapters/src/types.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.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/chain-adapters/src/types.ts
  • packages/chain-adapters/src/tron/types.ts
  • src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx
📚 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/swapperApi/getTradeQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.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/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.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/swapperApi/getTradeQuote.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.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/swapperApi/getTradeQuote.ts
  • src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.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/swapperApi/getTradeQuote.ts
  • src/components/Modals/Send/hooks/useSendDetails/useSendDetails.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 : Avoid side effects in swap logic; ensure swap methods are deterministic and stateless

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.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/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.ts
  • src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts
📚 Learning: 2025-12-04T11:05:01.112Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11281
File: packages/swapper/src/swappers/PortalsSwapper/utils/fetchSquidStatus.ts:98-106
Timestamp: 2025-12-04T11:05:01.112Z
Learning: In packages/swapper/src/swappers/PortalsSwapper/utils/fetchSquidStatus.ts, getSquidTrackingLink should return blockchain explorer links (using Asset.explorerTxLink) rather than API endpoints. For non-GMP Squid swaps: return source chain explorer link with sourceTxHash when pending/failed, and destination chain explorer link with destinationTxHash when confirmed.

Applied to files:

  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeQuote.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/chain-adapters/src/tron/TronChainAdapter.ts
  • src/components/Modals/Send/utils.ts
  • src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx
📚 Learning: 2025-10-21T17:11:18.087Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10871
File: src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx:426-428
Timestamp: 2025-10-21T17:11:18.087Z
Learning: In src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx, within the handleInputChange function, use .toFixed() without arguments (not .toString()) when converting BigNumber amounts for input field synchronization. This avoids exponential notation in the input while preserving precision for presentational components like <Amount.Crypto /> and <Amount.Fiat /> to format appropriately.

Applied to files:

  • src/components/Modals/Send/utils.ts
  • src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx
📚 Learning: 2025-08-05T22:41:35.473Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10187
File: src/pages/Assets/Asset.tsx:1-1
Timestamp: 2025-08-05T22:41:35.473Z
Learning: In the shapeshift/web codebase, component imports use direct file paths like '@/components/ComponentName/ComponentName' rather than barrel exports. The AssetAccountDetails component should be imported as '@/components/AssetAccountDetails/AssetAccountDetails', not from a directory index.

Applied to files:

  • src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx
📚 Learning: 2025-08-05T23:36:13.214Z
Learnt from: premiumjibles
Repo: shapeshift/web PR: 10187
File: src/state/slices/preferencesSlice/selectors.ts:21-25
Timestamp: 2025-08-05T23:36:13.214Z
Learning: The AssetId type from 'shapeshiftoss/caip' package is a string type alias, so it can be used directly as a return type for cache key resolvers in re-reselect selectors without needing explicit string conversion.

Applied to files:

  • src/components/Modals/Send/hooks/useSendDetails/useSendDetails.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/Modals/Send/hooks/useSendDetails/useSendDetails.tsx
📚 Learning: 2025-12-03T23:21:16.985Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11261
File: src/lib/utils/tron/getAllowance.ts:14-59
Timestamp: 2025-12-03T23:21:16.985Z
Learning: In src/lib/utils/tron/getAllowance.ts, gomesalexandre is not concerned about adding comprehensive error handling (try-catch blocks, custom error classes) for the getTrc20Allowance utility function, because it is used close to the view layer. He prefers simpler error handling for view-layer utilities, letting errors propagate naturally rather than adding defensive guards.

Applied to files:

  • packages/unchained-client/src/tron/api.ts
  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.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/swapper/src/thorchain-utils/getL1RateOrQuote.ts
📚 Learning: 2025-08-05T16:39:58.598Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10191
File: src/pages/Explore/Explore.tsx:56-56
Timestamp: 2025-08-05T16:39:58.598Z
Learning: In the ShapeShift web codebase, the established pattern for handling floating point numbers is to use BigNumber operations (bnOrZero, bn) for calculations and convert to strings using .toString() before passing to UI components like Amount.Fiat, Amount.Crypto, and Amount.Percent. This prevents JavaScript floating point precision issues and maintains consistency across the application.

Applied to files:

  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.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/swapper/src/thorchain-utils/getL1RateOrQuote.ts
📚 Learning: 2025-07-24T11:07:20.536Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10073
File: src/features/defi/providers/fox-farming/components/FoxFarmingManager/Claim/Claim.tsx:77-84
Timestamp: 2025-07-24T11:07:20.536Z
Learning: In fox farming components, the `opportunity?.rewardsCryptoBaseUnit?.amounts` property has a well-defined type signature that is always an array (never undefined), but can be empty: `readonly [] | readonly [string, string, string] | readonly [string, string] | readonly [string]`. Using optional chaining on the `amounts` property itself is unnecessary since it's always defined, though accessing `amounts[0]` on an empty array returns undefined which bnOrZero() handles safely.

Applied to files:

  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts
📚 Learning: 2025-11-18T09:52:51.368Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10334
File: src/lib/user/api.ts:46-105
Timestamp: 2025-11-18T09:52:51.368Z
Learning: In the shapeshift/web repository, monadic error-handling with Result types (Ok/Err from sniptt/monads) is specific to the swapper domain and is not used anywhere else in the codebase. API helpers outside the swapper domain (e.g., user API, notification services) should use traditional throw/catch error handling patterns instead of Result monads.

Applied to files:

  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.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} : 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

Applied to files:

  • packages/swapper/src/thorchain-utils/getL1RateOrQuote.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/thorchain-utils/getL1RateOrQuote.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/thorchain-utils/getL1RateOrQuote.ts
  • packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.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/thorchain-utils/getL1RateOrQuote.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/swapperApi/getTradeRate.ts
🧬 Code graph analysis (5)
packages/chain-adapters/src/types.ts (6)
packages/caip/src/adapters/coingecko/generated/index.ts (1)
  • tron (42-42)
packages/utils/src/assetData/baseAssets.ts (1)
  • tron (339-353)
packages/chain-adapters/src/tron/types.ts (1)
  • GetFeeDataInput (24-28)
packages/chain-adapters/src/sui/types.ts (1)
  • GetFeeDataInput (19-22)
packages/chain-adapters/src/evm/types.ts (1)
  • GetFeeDataInput (82-87)
packages/chain-adapters/src/solana/types.ts (1)
  • GetFeeDataInput (31-36)
packages/chain-adapters/src/tron/types.ts (1)
packages/chain-adapters/src/types.ts (1)
  • GetFeeDataInput (326-333)
packages/chain-adapters/src/tron/TronChainAdapter.ts (2)
packages/chain-adapters/src/tron/types.ts (1)
  • GetFeeDataInput (24-28)
packages/chain-adapters/src/types.ts (2)
  • GetFeeDataInput (326-333)
  • FeeDataEstimate (107-111)
src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx (1)
src/components/Modals/Send/utils.ts (1)
  • estimateFees (58-160)
packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts (3)
packages/utils/src/index.ts (1)
  • contractAddressOrUndefined (46-47)
packages/caip/src/adapters/coingecko/generated/index.ts (1)
  • tron (42-42)
packages/utils/src/assetData/baseAssets.ts (1)
  • tron (339-353)
⏰ 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)
packages/unchained-client/src/tron/api.ts (1)

243-244: LGTM! More realistic TRC20 fallback.

The reduced fallback from 31 TRX to 13 TRX (130k energy at 100 sun/energy) provides a more accurate worst-case estimate for TRC20 transfers when dynamic estimation fails. The comment clearly documents the assumption.

src/components/Modals/Send/hooks/useSendDetails/useSendDetails.tsx (1)

111-116: LGTM! Correct derivation of from address.

The from address is correctly derived using fromAccountId(accountId) and passed to estimateFees. The dependency array correctly includes accountId (the source) rather than from (the derived value), which is the appropriate pattern for stable utility derivations.

src/components/Modals/Send/utils.ts (1)

136-140: LGTM! Proper Tron fee data input.

The chainSpecific object correctly includes from, contractAddress, and memo fields for Tron fee estimation. This aligns with the new tron.GetFeeDataInput type and enables the adapter to differentiate between TRC20 and TRX transfers and handle memo-based fee adjustments.

packages/swapper/src/swappers/NearIntentsSwapper/swapperApi/getTradeRate.ts (1)

224-237: LGTM! Appropriate Tron fee data for rate context.

The empty chainSpecific object is correct for rate estimation without wallet context. Since all fields in tron.GetFeeDataInput are optional, the adapter can use default fee estimation logic when specific transaction details aren't available.

packages/chain-adapters/src/types.ts (1)

323-323: LGTM! Proper Tron type mapping.

The TronMainnet entry correctly maps to tron.GetFeeDataInput in the ChainSpecificGetFeeDataInput type, following the established pattern for other chains and enabling type-safe Tron fee data requests.

packages/chain-adapters/src/tron/types.ts (1)

24-28: LGTM! Well-designed Tron fee input type.

The GetFeeDataInput type appropriately defines optional fields that enable:

  • from: Sender address for accurate TRC20 energy estimation
  • contractAddress: TRC20 vs TRX transfer detection
  • memo: Memo-based fee adjustment (1 TRX per memo)

The optional design provides flexibility for rate estimation (no wallet) vs quote contexts (wallet connected).

packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts (1)

8-8: LGTM! Necessary imports for Tron integration.

The imports properly support Tron fee estimation: TronWeb for chain queries, contractAddressOrUndefined for TRC20 detection, and the tron namespace for THORChain-specific utilities.

Also applies to: 18-18, 46-46

Comment thread packages/swapper/src/thorchain-utils/getL1RateOrQuote.ts Outdated
gomesalexandre and others added 2 commits December 4, 2025 19:30
…h calculation

After the mergefix, the Tron GetFeeDataInput type now requires chainSpecific
parameter with from, contractAddress, and memo fields. Updated all callers:

- SunioSwapper: Pass from, contractAddress to estimate swap fees correctly
- useApprovalFees: Pass from, contractAddress for approval tx estimation
- Fixed memo fee calculation to scale with memo byte length instead of flat 1 TRX

Also addressed CodeRabbit feedback: Memo data adds to transaction bandwidth
proportionally to byte length, not as a separate flat fee. Removed the
redundant 1 TRX memo fee and properly calculate bandwidth based on actual
memo size in both chain adapter and swapper code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

@NeOMakinG NeOMakinG left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@NeOMakinG
NeOMakinG merged commit 6f6b9cd into develop Dec 5, 2025
4 checks passed
@NeOMakinG
NeOMakinG deleted the fix_tron_estimates branch December 5, 2025 11:47
gomesalexandre added a commit that referenced this pull request Dec 5, 2025
Resolved conflicts from squash-merged PR #11274 (Sun.io integration):
- TronChainAdapter.ts: kept improved fee estimation with from parameter and account activation
- SunioSwapper/getQuoteOrRate.ts: kept detailed TronWeb-based fee estimation (this PR's feature)
- NearIntents files: kept proper chainSpecific params with from and contractAddress

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai coderabbitai Bot mentioned this pull request Dec 8, 2025
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.

CRITICAL: TRON TRC20 Fee Estimation Underestimates by 24-48x, Causing Failed Transactions

2 participants