Conversation
Fixes incomplete transaction parsing for TRX → USDT swaps where only the USDT receive was shown but the TRX send was missing. The issue occurred when users swap through a router contract. The transaction flow is: 1. User initiates swap by calling router contract 2. Router sends user's TRX to swap pool (internal transaction) 3. Swap pool sends USDT back to user Previously, internal transactions were only detected if the caller or recipient matched the user's pubkey. This missed the TRX send because the router contract was the caller, not the user. The fix extracts the transaction initiator from raw_data.contract[0] and uses it to identify user-initiated internal transfers. When a contract sends TRX on behalf of the user, we now create a Send transfer with the user as the "from" address. Added diagnostic logging to track RPC responses and transfer parsing for debugging. Logs will be removed after testing confirms the fix. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe TronChainAdapter now extracts a transaction initiator from contract parameters and passes it into internal TRX transfer parsing. Parsing logic moves from send/receive binary checks to three-state logic (isDirectSend, isDirectReceive, isInitiatedByUser) to attribute transfers correctly. Changes
Sequence Diagram(s)(omitted — change is internal parsing logic without multi-component sequential flow requiring visualization) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Clean up console logs added during investigation. All logs removed: - RPC response logging in api.ts - TRC20 transfer parsing logs - Internal transfer parsing logs - Final combined transfer logs Core fix remains: detecting TRX sends in user-initiated swap transactions by correlating transaction initiator with internal transfers. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
https://jam.dev/c/27e7903f-80fa-42e7-b749-50e4f78f8359
Looks good overall
Noticed 2 things:
- USDT send were not upserted in the history
- We have a lot of rate limit issues preventing us from sending the first time
We don't have any throttler anymore in the TRON adapter, not sure we ever had but we definitely need to add one there to fix that issue!
@coderabbitai can you create an issue to add a throttle to the TronChainAdapter?
|
@coderabbitai can you create an issue to add a throttle to the TronChainAdapter? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 46 @NeOMakinG: I've created issue #11543 to add throttle functionality to the TronChainAdapter. The issue has been assigned to you and includes context from this PR. 🧠 Learnings used |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Organization 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.
📒 Files selected for processing (1)
packages/chain-adapters/src/tron/TronChainAdapter.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Never assume a library is available - always check imports/package.json first
Prefer composition over inheritance
Write self-documenting code with clear variable and function names
Keep functions small and focused on a single responsibility
Avoid deep nesting - use early returns instead
Prefer procedural and easy to understand code
Never expose, log, or commit secrets, API keys, or credentials
Validate all inputs, especially user inputs
Handle errors gracefully with meaningful messages
Don't silently catch and ignore exceptions
Log errors appropriately for debugging
Provide fallback behavior when possible
Use appropriate data structures for the task
Never add code comments unless explicitly requested
When modifying code, do not add comments that reference previous implementations or explain what changed. Comments should only describe the current logic and functionality.
Use meaningful names for branches, variables, and functions
Always runyarn lint --fixandyarn type-checkafter making changes
Avoidletvariable assignments - preferconstwith inline IIFE switch statements or extract to functions for conditional logic
Files:
packages/chain-adapters/src/tron/TronChainAdapter.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 inuseMemoand callbacks inuseCallbackwhere 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 usinguseColorModeValuehook
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()fromreact-polyglot
UseuseFeatureFlag('FlagName')hook to access feature flag values in components
Prefertypeoverinterfacefor type definitions
Use strict typing - avoidany
UseNominaltypes for domain identifiers (e.g.,WalletId,AccountId)
Import types from@shapeshiftoss/caipfor chain/account/asset IDs
UseuseAppSelectorfor Redux state
UseuseAppDispatchfor Redux actions
Memoize expensive computations withuseMemo
Memoize callbacks withuseCallback
**/*.{ts,tsx}: UseResult<T, E>pattern for error handling in swappers and APIs; ALWAYS useOk()andErr()from@sniptt/monads; AVOID throwing within swapper API implementations
ALWAYS use custom error classes from@shapeshiftoss/errorswith meaningful error codes for internationalization and relevant details in error objects
ALWAYS wrap async op...
Files:
packages/chain-adapters/src/tron/TronChainAdapter.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
Usehandleprefix for event handlers with descriptive names in camelCase
Use descriptive boolean variable names withis,has,can,shouldprefixes
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 likedata,item,obj, and single-letter variable names except in loops
Avoid abbreviations in names unless they are widely understood
Avoid generic function names likefn,func, orcallback
Files:
packages/chain-adapters/src/tron/TronChainAdapter.ts
🧠 Learnings (3)
📓 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: 11449
File: packages/chain-adapters/src/tron/TronChainAdapter.ts:570-596
Timestamp: 2025-12-17T14:50:01.629Z
Learning: In packages/chain-adapters/src/tron/TronChainAdapter.ts, the parseTx method uses `unknown` type for the txHashOrTx parameter intentionally. TRON is a "second-class chain" that works differently from other chains - it accepts either a string hash (to fetch TronTx via unchained client) or a TronTx object directly. The base chain-adapter interface is strongly typed and doesn't accommodate this flexible signature, so `unknown` is used as an appropriate escape hatch rather than a type safety issue.
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: 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.
Learnt from: NeOMakinG
Repo: shapeshift/web PR: 10376
File: packages/contracts/src/viemClient.ts:39-40
Timestamp: 2025-08-27T09:51:36.901Z
Learning: NeOMakinG confirmed that issues flagged by CodeRabbit that predate the PR changes and are unrelated to the PR's core objective should be addressed separately, not within the current PR scope.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/utils/tenderly/index.ts:0-0
Timestamp: 2025-09-12T11:56:19.437Z
Learning: gomesalexandre rejected verbose try/catch error handling for address validation in Tenderly integration (PR #10461), calling the approach "ugly" but still implemented safety measures in commit ad7e424b89, preferring cleaner safety implementations over defensive programming patterns.
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/modals/EIP712MessageDisplay.tsx:21-24
Timestamp: 2025-09-12T13:16:27.004Z
Learning: gomesalexandre declined to add error boundaries to WalletConnect modals in PR #10461, stating "no error boundaries in this pr ser", consistent with his preference to keep PR scope focused and defer tangential improvements to separate efforts.
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-12-17T14:50:01.629Z
Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11449
File: packages/chain-adapters/src/tron/TronChainAdapter.ts:570-596
Timestamp: 2025-12-17T14:50:01.629Z
Learning: In packages/chain-adapters/src/tron/TronChainAdapter.ts, the parseTx method uses `unknown` type for the txHashOrTx parameter intentionally. TRON is a "second-class chain" that works differently from other chains - it accepts either a string hash (to fetch TronTx via unchained client) or a TronTx object directly. The base chain-adapter interface is strongly typed and doesn't accommodate this flexible signature, so `unknown` is used as an appropriate escape hatch rather than a type safety issue.
Applied to files:
packages/chain-adapters/src/tron/TronChainAdapter.ts
📚 Learning: 2025-12-04T22:57:50.850Z
Learnt from: kaladinlight
Repo: shapeshift/web PR: 11290
File: packages/chain-adapters/src/utxo/zcash/ZcashChainAdapter.ts:48-51
Timestamp: 2025-12-04T22:57:50.850Z
Learning: In packages/chain-adapters/src/**/*ChainAdapter.ts files, the getName() method uses the pattern `const enumIndex = Object.values(ChainAdapterDisplayName).indexOf(ChainAdapterDisplayName.XXX); return Object.keys(ChainAdapterDisplayName)[enumIndex]` to reverse-lookup the enum key from its value. This is the established pattern used consistently across almost all chain adapters (Bitcoin, Ethereum, Litecoin, Dogecoin, Polygon, Arbitrum, Cosmos, etc.) and should be preserved for consistency when adding new chain adapters.
Applied to files:
packages/chain-adapters/src/tron/TronChainAdapter.ts
🧬 Code graph analysis (1)
packages/chain-adapters/src/tron/TronChainAdapter.ts (1)
packages/chain-adapters/src/types.ts (1)
TransferType(133-133)
⏰ 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 (4)
packages/chain-adapters/src/tron/TronChainAdapter.ts (4)
611-611: LGTM! Parameter passing is consistent with signature change.The extracted
txInitiatoris correctly passed toparseInternalTrxTransfers.
700-700: LGTM! Method signature change is appropriate.Adding the optional
txInitiatorparameter is a clean extension that maintains backward compatibility for this private method.
743-769: LGTM! Logic structure correctly handles router-forwarded TRX sends.The implementation properly distinguishes between:
- Direct sends (user is caller)
- User-initiated sends forwarded by router (user is initiator, router is caller)
- Direct receives (user is recipient)
The mutually exclusive if-else-if for Send logic combined with the separate Receive check is correct, as Line 735 prevents
caller_address === transferTo_address. Edge case handling (rejected transactions, missing data, token transfers, zero values) is comprehensive.This fix successfully addresses the issue where TRX → USDT swaps via router contracts showed only the USDT receive without the TRX send.
739-741: The three-state logic is correct and type-safe—no changes needed.The code correctly identifies three transfer states: direct sends, direct receives, and user-initiated but router-forwarded transfers. The
isInitiatedByUsercondition ensurestxInitiatoris safely narrowed tostring(not undefined) since the condition includestxInitiator === pubkey, which guards against undefined values.TypeScript type-checking passes without errors for this code pattern.
Description
Fixes incomplete transaction parsing for TRX → USDT swaps where only the USDT receive was shown but the TRX send was missing (#11526).
The issue occurred when users swap through a router contract. The transaction flow is:
Previously, internal transactions were only detected if the caller or recipient matched the user's pubkey. This missed the TRX send because the router contract was the caller, not the user.
The fix extracts the transaction initiator from
raw_data.contract[0].parameter.value.owner_addressand uses it to identify user-initiated internal transfers. When a contract sends TRX on behalf of the user, we now create a Send transfer with the user as the "from" address.Note: Includes diagnostic logging for testing. Logs will be removed after verification.
Issue (if applicable)
closes #11526
Risk
Testing
Engineering
[TRON_*]prefixed diagnostic outputOperations
Screenshots (if applicable)
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.