Skip to content

fix: tron trc20 balances for non-activated accounts + send warning#12191

Merged
gomesalexandre merged 5 commits intodevelopfrom
fix/tron-non-activated-balances
Mar 19, 2026
Merged

fix: tron trc20 balances for non-activated accounts + send warning#12191
gomesalexandre merged 5 commits intodevelopfrom
fix/tron-non-activated-balances

Conversation

@gomesalexandre
Copy link
Contributor

@gomesalexandre gomesalexandre commented Mar 18, 2026

Description

Two fixes for Tron non-activated accounts:

  1. TRC20 balance discovery for non-activated accounts - The TronGrid /v1/accounts/{addr} API returns {"data":[]} for addresses that have never sent TRX (non-activated). Added a fallback in TronApi.getAccount() that checks hardcoded top tokens (USDT, USDC) + scans received TRC20 tx history to discover token contracts, then calls balanceOf() via triggerconstantcontract. Non-activated accounts with USDT/TRC20 balances now show up in the portfolio.

  2. Send flow warning for non-activated recipient - Added useIsTronAddressActivated hook that checks if a Tron recipient address is activated. On the send amount screen, if the recipient is non-activated and the asset is not native TRX, a yellow warning alert is shown: "This address hasn't been activated on Tron yet. Your tokens will arrive, but the recipient won't be able to move them until they also receive some TRX." Warn-and-allow - send is not blocked.

Issue (if applicable)

closes #12190

Risk

Low - Tron-specific changes, under the TRON feature flag. The balance fallback only triggers for non-activated accounts (empty data[] response from TronGrid). The send warning is informational only and doesn't block the flow.

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

Tron TRC20 token sends only.

Testing

Engineering

  1. Use a Tron address that has received USDT but has 0 TRX (non-activated)
  2. Add it to ShapeShift - USDT balance should now show in the portfolio
  3. Open the send flow for USDT (Tron), enter a non-activated Tron recipient address
  4. Verify the yellow warning appears on the amount screen

qabot run (6/6 passed): http://localhost:8080/runs/99d0a229-c7e4-49b3-b7d5-a3b93922f5d5

Operations

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

Tron is behind the VITE_FEATURE_TRON flag.

Summary by CodeRabbit

  • Bug Fixes

    • Better discovery of TRC20 balances for Tron accounts missing on-chain token listings.
    • Activity detection now counts Tron token balances when evaluating account activity.
  • New Features

    • User-facing warning when sending to non-activated Tron addresses; send flow remains available.
    • On-send validation checks for Tron address activation.
  • Tests

    • End-to-end test added for non-activated Tron recipient behavior.
  • Documentation

    • New translation text for the non-activated Tron recipient warning.

gomesalexandre and others added 2 commits March 18, 2026 14:02
- TronApi: fallback for non-activated accounts - uses hardcoded top tokens
  (USDT, USDC) + received TRC20 tx history discovery, then balanceOf() via
  triggerconstantcontract to fetch balances that TronGrid /v1/accounts skips
- portfolioSlice utils: checkAccountHasActivity now checks token balances
  so non-activated accounts with TRC20 tokens aren't skipped
- useIsTronAddressActivated: new hook to check if a Tron recipient address
  has been activated on-chain (checks for address property in response)
- SendAmountDetails: warning shown when sending TRC20 to non-activated
  recipient (suppressed for native TRX sends which activate the account)

Closes #12190

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@gomesalexandre gomesalexandre requested a review from a team as a code owner March 18, 2026 13:46
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 18, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e0a24b1e-23df-444f-815a-bb998d8f8eb9

📥 Commits

Reviewing files that changed from the base of the PR and between e16846f and e118aae.

📒 Files selected for processing (1)
  • packages/unchained-client/src/tron/api.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/unchained-client/src/tron/api.ts

📝 Walkthrough

Walkthrough

Adds TRC20 discovery fallback for Tron, updates portfolio activity detection for Tron tokens, introduces a hook that queries Tron RPC to check address activation, surfaces a send-modal warning for non-activated Tron recipients, and adds an e2e fixture validating the warning for USDT/TRC20 recipients.

Changes

Cohort / File(s) Summary
Tron TRC20 Balance Discovery Fallback
packages/unchained-client/src/tron/api.ts
When canonical account data is missing, discovers TRC20 contracts from recent TRC20 txs (seeded with USDT/USDC), fetches balanceOf per contract, and appends non-zero token balances as a fallback.
Portfolio Activity Detection
src/state/slices/portfolioSlice/utils/index.ts
Tron account activity now counts either a positive account.balance or any token in tronAccount.chainSpecific.tokens with a positive balance.
Recipient Activation Hook
src/hooks/useIsTronAddressActivated/useIsTronAddressActivated.ts
New React Query hook that posts to Tron RPC /wallet/getaccount to determine if a Tron address is activated; exposes query state with a 30s stale time.
Send UI Warning & Translations
src/components/Modals/Send/views/SendAmountDetails.tsx, src/assets/translations/en/main.json
Integrates the activation hook into the send modal and renders a localized warning when a Tron recipient is detected as not activated; adds translation key tron.recipientNotActivated.sendWarning.
End-to-End Test Fixture
e2e/fixtures/tron-non-activated-balances.yaml
New e2e fixture that opens Tron USDT, inputs a known non-activated Tron address, waits for validation, and asserts the recipient-not-activated warning appears while Continue remains enabled.

Sequence Diagram

sequenceDiagram
    participant User
    participant SendUI as SendAmountDetails
    participant Hook as useIsTronAddressActivated
    participant Query as ReactQuery
    participant TronRPC as Tron RPC

    User->>SendUI: open send modal, select USDT, enter recipient (T...)
    SendUI->>Hook: call useIsTronAddressActivated(to, chainId)
    Hook->>Query: register/query ['isTronAddressActivated', to, chainId]
    Query->>TronRPC: POST /wallet/getaccount {address}
    TronRPC-->>Query: return account data (address present or empty)
    Query-->>Hook: activation status (true/false/undefined)
    Hook-->>SendUI: isTronRecipientActivated = false
    SendUI->>User: render yellow/orange warning "recipient hasn't activated Tron"
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I sniffed the ledger, hopped over a log,
Found USDT napping on a Tron-only bog.
I poked with a hook, queried the chain,
Warned with a carrot-colored banner again,
Now balances whisper once TRX clears the fog. 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title directly and clearly summarizes the main changes: fixing TRC20 balance discovery for non-activated Tron accounts and adding a send-flow warning for such recipients.
Linked Issues check ✅ Passed The PR fully implements the acceptance criteria from #12190: TRC20 tokens now appear on non-activated Tron accounts via fallback balance discovery, and a send warning alerts users when sending tokens to non-activated recipients.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the linked issue: TRC20 fallback discovery, send-flow warning, activity detection, and supporting infrastructure are all necessary to meet the requirement that tokens show on non-activated accounts.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/tron-non-activated-balances
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@e2e/fixtures/tron-non-activated-balances.yaml`:
- Around line 31-39: The fixture "Verify non-activated recipient warning shows"
currently asserts that the Continue/Preview button is enabled without entering
an amount; update the instruction block for that test to include an explicit
amount-entry step (e.g., type a valid numeric value into the amount field on the
send amount screen) before the expected assertion so the Continue/Preview
enabled check is deterministic.
- Around line 9-11: The fixture's instruction incorrectly navigates to
"/assets/eip155:195/slip44:195" (which is TRX) instead of the Tron USDT asset;
update the instruction under "Navigate to Tron USDT asset page" to point to the
correct Tron USDT asset route (replace "/assets/eip155:195/slip44:195" with the
proper Tron USDT asset path) or explicitly instruct the test to search for "USDT
on Tron" in the asset list so the test lands on the USDT (Tron) page rather than
the native TRX page.

In `@packages/unchained-client/src/tron/api.ts`:
- Around line 112-119: The current fallback fans out unbounded RPC calls by
using Promise.all over discoveredContracts which can flood providers; change the
logic that builds balanceResults to throttle concurrent getTRC20Balance calls
(e.g., process discoveredContracts in small batches or use a concurrency
limiter) so only N calls run concurrently, retry transient failures if desired,
and collect { contractAddress, balance } results the same way; update the code
that references balanceResults and the Promise.all usage to use the new
batched/limited executor for getTRC20Balance.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7dec60bf-646e-4981-91d6-c9f87b880c89

📥 Commits

Reviewing files that changed from the base of the PR and between 865d7d0 and d849fc0.

📒 Files selected for processing (6)
  • e2e/fixtures/tron-non-activated-balances.yaml
  • packages/unchained-client/src/tron/api.ts
  • src/assets/translations/en/main.json
  • src/components/Modals/Send/views/SendAmountDetails.tsx
  • src/hooks/useIsTronAddressActivated/useIsTronAddressActivated.ts
  • src/state/slices/portfolioSlice/utils/index.ts

- throttle balanceOf calls sequentially instead of Promise.all fanout
- fix fixture: use correct tron:0x2b6653dc/trc20:... USDT asset route
- fix fixture: separate warning assertion from preview-enabled assertion

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@gomesalexandre
Copy link
Contributor Author

addressed @coderabbitai comments:

  • fixture route: fixed to tron:0x2b6653dc/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t (the suggested fix was also wrong - eip155 namespace doesn't apply to Tron)
  • preview assertion: split into two steps - warning visibility separate from amount-entry + preview-enabled check
  • Promise.all fanout: applied the sequential throttle loop; fair point even if in practice this path starts with only 2 hardcoded contracts

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 18, 2026

Tip

For best results, initiate chat on the files or code changes.

@gomesalexandre Thanks for the fixes and the correction on the fixture route — you're right, eip155 namespace doesn't apply to Tron and my suggested fix was equally wrong. The tron:0x2b6653dc/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t format is the correct CAIP namespace. All three items look well-addressed!


🧠 Learnings used
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: 10461
File: src/plugins/walletConnectToDapps/hooks/useSimulateEvmTransaction.ts:91-95
Timestamp: 2025-09-12T13:43:50.695Z
Learning: gomesalexandre dismissed gas calculation overflow validation in useSimulateEvmTransaction hook as "stale", preferring to trust Tenderly's simulation data without defensive validation checks, consistent with his established pattern of relying on external service quality over defensive programming in WalletConnect flows.

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/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: gomesalexandre
Repo: shapeshift/web PR: 10458
File: src/plugins/walletConnectToDapps/components/modals/EIP155SignTypedDataConfirmation.tsx:55-55
Timestamp: 2025-09-10T15:35:46.223Z
Learning: gomesalexandre prefers fail-fast early returns over graceful degradation when critical data is missing in WalletConnect flows (like peer metadata in EIP155SignTypedDataConfirmation.tsx). He favors "safety first, always double-wrap" approach and believes missing peer metadata indicates bigger problems that should be surfaced explicitly rather than masked with partial UI rendering.

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

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/components/modals/SendTransactionConfirmation.tsx:42-50
Timestamp: 2025-09-12T12:00:33.924Z
Learning: gomesalexandre prefers maintaining consistency with existing code patterns across WalletConnect modal components, including side-effects-during-render for error handling (showErrorToast + handleReject calls before return null), rather than introducing isolated refactors that would create inconsistency in the codebase.

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

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10461
File: src/plugins/walletConnectToDapps/components/WalletConnectSigningModal/content/TransactionContent.tsx:40-140
Timestamp: 2025-09-12T12:04:24.562Z
Learning: gomesalexandre prefers to defer error handling improvements in new/preparatory code until real-world error cases are encountered, rather than implementing speculative error handling without concrete failure scenarios to test against. This aligns with keeping PR scope focused and evidence-based development practices.

Learnt from: gomes-bot
Repo: shapeshift/web PR: 11884
File: packages/chain-adapters/src/tron/TronChainAdapter.ts:732-735
Timestamp: 2026-02-16T15:00:09.111Z
Learning: In packages/chain-adapters/src/tron/TronChainAdapter.ts, inline comments explaining non-obvious domain-specific behavior (e.g., why TRC20 burns to zero address are allowed while mints from zero address are skipped) are acceptable when explicitly requested, especially when the rationale is easy to regress (e.g., sTRX unstaking burn behavior).

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10751
File: src/Routes/RoutesCommon.tsx:190-190
Timestamp: 2025-10-13T11:55:57.439Z
Learning: In the shapeshift/web codebase, there are multiple independent claim systems: Arbitrum bridge claims (removed in PR `#10751`), RFOX claims (in src/pages/RFOX/components/Claim/), and TCY claims (in src/pages/TCY/). Each has its own routes, components, and logic. When reviewing claim-related changes, distinguish which system is being modified and avoid suggesting changes to unrelated claim systems.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 12111
File: packages/swapper/src/swappers/BebopSwapper/utils/fetchFromBebop.ts:208-224
Timestamp: 2026-03-07T14:20:46.655Z
Learning: In packages/swapper/src/swappers/BebopSwapper/utils/fetchFromBebop.ts, the shared Solana fetcher `fetchBebopSolanaQuote` always sends `gasless=true` in its query params. The Bebop Solana API guarantees `QUOTE_SUCCESS` status and a `solana_tx` field in responses when `gasless=true` is used, regardless of whether the taker/receiver address is a real address or a dummy address (BEBOP_SOLANA_DUMMY_ADDRESS). The `QUOTE_INDIC_ROUTE` status only occurs with `gasless=false&skip_validation=true`, which is not used. Therefore, enforcing `status === 'QUOTE_SUCCESS'` and `solana_tx` presence in the shared fetcher is correct and does not incorrectly block the rate/price path.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 11335
File: packages/swapper/src/swappers/CetusSwapper/endpoints.ts:66-68
Timestamp: 2025-12-09T21:06:15.748Z
Learning: In packages/swapper/src/swappers/CetusSwapper/endpoints.ts, gomesalexandre is comfortable with throwing errors directly in getUnsignedSuiTransaction and similar transaction preparation methods, rather than using the Result pattern. The Result pattern with makeSwapErrorRight/TradeQuoteError is primarily for the main swapper API methods (getTradeQuote, getTradeRate), while helper/preparation methods can use throws.

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

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 12136
File: src/lib/solanaJitoBundle.ts:39-42
Timestamp: 2026-03-11T16:15:29.382Z
Learning: In src/lib/solanaJitoBundle.ts, gomesalexandre is comfortable with a naive midpoint instruction split for Jito bundle creation. Butter guarantees ~20-30 instructions for oversized Solana transactions (which is why they're oversized), so a simple Math.ceil(length/2) split is acceptable for MVP without byte-size validation or rebalancing. Edge cases can be handled iteratively.

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.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 10879
File: src/context/WalletProvider/WalletConnectV2/components/WalletConnectDirectRow.tsx:64-81
Timestamp: 2025-10-22T22:11:22.918Z
Learning: In early WalletConnect POC/features behind a flag, gomesalexandre prioritizes connection correctness/stability over UX polish; minimal safety guards (like preventing concurrent connects) are preferred, while visuals will be wired later by reallybeard.

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: 0
File: :0-0
Timestamp: 2026-03-17T21:54:13.597Z
Learning: In shapeshift/web, the batch-prefetch in src/lib/account/evm.ts gates on `wallet.ethGetAddresses`, which is chain-agnostic and works for any EVM-capable wallet regardless of chain-specific support flags like `supportsAbstract`. The chain-specific `supports*` guard is enforced downstream in `deriveEvmAccountIdsAndMetadata`. This pattern is identical across all second-class EVM chains and should not be flagged as a missing pre-check.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 0
File: :0-0
Timestamp: 2026-03-17T01:29:21.619Z
Learning: In shapeshift/web PR `#12181`, the primary fix is replacing SHA-based comparison (`privateSha`) with a content diff approach (`privateContentMatchesMain` boolean) in `deriveReleaseState`/`deriveHotfixState` in `scripts/release.ts`. This unblocks new releases when `private` has been squash-synced with `main` (SHA differs even though content is identical). The secondary fix — `createPr` returning `null` on "No commits between" GitHub error — is a defensive improvement bundled in the same PR. The PR title only references the secondary change; the commit message body captures both.

Learnt from: gomesalexandre
Repo: shapeshift/web PR: 0
File: :0-0
Timestamp: 2026-03-17T20:28:34.883Z
Learning: In shapeshift/web, chains added to `walletConnectV2OptionalChains` and `rpcMap` in `src/context/WalletProvider/WalletConnectV2/config.ts` are intentionally NOT gated by their feature flags. Feature-flagged chains (e.g., ink, flowEvmChain, sei, abstract) are unconditionally included in these WalletConnect V2 structures. This is the established convention and should not be flagged as a missing feature-flag guard.

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: gomes-bot
Repo: shapeshift/web PR: 11916
File: src/plugins/walletConnectToDapps/utils/BIP122RequestHandlerUtil.ts:274-310
Timestamp: 2026-02-18T17:59:47.245Z
Learning: In src/plugins/walletConnectToDapps/utils/BIP122RequestHandlerUtil.ts, the hardcoded `accountNumber: 0` in the BIP122_SEND_TRANSFER handler is intentional. WalletConnect BIP122 sessions expose derived addresses (bc1q/3/1) rather than xpub-based accountIds, so there's no account metadata available to extract accountNumber from. Multi-account support would require account selection UI wired through the BIP122 modal chain.

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/unchained-client/src/tron/api.ts`:
- Around line 117-119: In getTRC20Balance's fallback catch block that currently
swallows _fallbackErr, record the failure before continuing: emit a breadcrumb
or log (e.g., Sentry.addBreadcrumb or processLogger.warn/processLogger.error)
including the error object and context (token address, wallet address, and that
the fallback path failed) so the partial token list return is discoverable;
update the catch surrounding _fallbackErr to call the project's telemetry/logger
with those details and then continue returning the partial results.
- Around line 97-115: getAccount() currently iterates up to 200 inbound TRC20
transfers and then serially runs this.throttle() + getTRC20Balance() for every
entry in discoveredContracts, which can stall the shared requestQueue; limit the
probe set by adding a hard cap (e.g. MAX_FALLBACK_CONTRACT_PROBES) and only
probe the most relevant contracts (most recent or highest-value) before calling
getTRC20Balance(), or alternatively make the probes fire off as non-blocking
background tasks rather than blocking getAccount() (reference
discoveredContracts, throttle(), getTRC20Balance(), tokens, and the shared
requestQueue/TronApi instance when implementing).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 71705778-7def-4cab-bb79-3a3cf1ba3072

📥 Commits

Reviewing files that changed from the base of the PR and between d849fc0 and e16846f.

📒 Files selected for processing (2)
  • e2e/fixtures/tron-non-activated-balances.yaml
  • packages/unchained-client/src/tron/api.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • e2e/fixtures/tron-non-activated-balances.yaml

- add MAX_FALLBACK_CONTRACTS = 20 ceiling to prevent stalling shared requestQueue
- log fallback discovery errors instead of silently swallowing them

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@NeOMakinG
Copy link
Collaborator

🤖 QA Test Report - PR #12191

Status:PASSED

Test Summary

Testing TRON TRC20 balance discovery for non-activated accounts and send warning UI.

Test Results

Step Status Details
Wallet Import ✅ Pass Successfully imported Native wallet via seed phrase
Portfolio Navigation ✅ Pass Navigated to Explore > Tokens to view all assets
TRON USDT Balance ✅ Pass TRON USDT balance (/bin/zsh.63) correctly displayed in portfolio
Send Modal ✅ Pass Opened Send Tether modal for TRON USDT
Non-Activated Warning ✅ Pass Warning displayed when entering non-activated recipient address

Verified Features

1. TRC20 Balance Discovery for Non-Activated Accounts

  • Code adds fallback in TronApi.getAccount() that checks hardcoded top tokens (USDT, USDC)
  • Scans received TRC20 transaction history to discover token contracts
  • Calls balanceOf() for each discovered contract
  • TRON USDT balance showing correctly in wallet

2. Send Warning for Non-Activated Recipients

  • Warning message displayed: 'This address hasn't been activated on Tron yet. Your tokens will arrive, but the recipient won't be able to move them until they also receive some TRX.'
  • Warning correctly shown only for TRC20 tokens (not native TRX)

Screenshots

  • Wallet connected with TRON USDT balance visible
  • Send warning displayed for non-activated recipient

Test Environment:

  • Branch: fix/tron-non-activated-balances
  • Device: Mac Mini (automated browser testing)
  • Date: 2026-03-18 18:07 UTC

Automated QA by OpenClaw

@NeOMakinG
Copy link
Collaborator

🤖 QA Test Report

Tested by: OpenClaw QA Bot
Date: 2026-03-19 06:06 UTC
Branch: fix/tron-non-activated-balances

✅ Test Results

Test Status
Wallet Connection ✅ Passed
TRX Balance Display ✅ Passed
Send UI Access ✅ Passed
Code Review ✅ Approved

📋 Findings

1. TRX Balances Display Correctly

2. Code Changes Review

  • checkAccountHasActivity now correctly considers TRC20 token balances (not just TRX)
  • ✅ New useIsTronAddressActivated hook properly checks recipient activation status
  • ✅ Warning message for non-activated recipients is clear and helpful
  • ✅ E2E test fixture added for non-activated balances scenario

3. Warning Message

"This address hasn't been activated on Tron yet. Your tokens will arrive, but the recipient won't be able to move them until they also receive some TRX."

📝 Notes

  • No TRC20 tokens in test wallet to verify TRC20-specific display
  • Send warning logic is correctly implemented (shows only for TRC20 sends, not TRX)
  • Fix properly addresses the issue of non-activated accounts not showing TRC20 balances

🎯 Recommendation

APPROVE - Code changes are well-implemented and follow best practices.

@gomesalexandre gomesalexandre enabled auto-merge (squash) March 19, 2026 08:30
@NeOMakinG
Copy link
Collaborator

✅ QA Test Passed

Test: Tron TRC20 Non-Activated Address Warning

Test Steps:

  1. Connected Native wallet
  2. Selected USDT (TRC20) on Tron chain
  3. Initiated send to non-activated Tron address: TYH7FhKrdNcmMZKnhTnxMR7VBL4Xzc3J9B
  4. Verified warning message displays correctly

Result:

The warning message appears as expected:

"This address hasn't been activated on Tron yet. Your tokens will arrive, but the recipient won't be able to move them until they also receive some TRX."

QABot Report:

https://qabot-kappa.vercel.app/runs/861a0ad0-e9fd-46b3-8d1e-b2067d777ba6


Automated QA by OpenClaw

Copy link
Collaborator

@NeOMakinG NeOMakinG left a comment

Choose a reason for hiding this comment

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

Tested the TRC20 non-activated address warning functionality. The warning displays correctly when attempting to send TRC20 tokens to an unactivated Tron address.

@gomesalexandre gomesalexandre merged commit 659cd52 into develop Mar 19, 2026
4 checks passed
@gomesalexandre gomesalexandre deleted the fix/tron-non-activated-balances branch March 19, 2026 09:00
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.

Usdt on tron not showing up in a wallet that has no trx balance

2 participants