Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions packages/swapper/src/swappers/RelaySwapper/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import {
soneiumChainId,
sonicChainId,
storyChainId,
tronChainId,
unichainChainId,
worldChainChainId,
zkSyncEraChainId,
Expand Down Expand Up @@ -87,7 +86,11 @@ export const chainIdToRelayChainId = {
[gnosisChainId]: gnosis.id,
[avalancheChainId]: avalanche.id,
[bscChainId]: bsc.id,
[tronChainId]: 728126428,
// DISABLED: Tron deposits are built as simple TRC20 transfers instead of depositErc20() vault calls,
// and the Relay indexer notification is never sent for non-EVM chains. This causes deposits to be
// untracked by Relay, resulting in stuck/lost funds. Re-enable once the Tron transaction building
// is verified to use the Relay quote calldata (depositErc20) correctly.
// [tronChainId]: 728126428,
Comment on lines +89 to +93
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove the inline “DISABLED” comment block.

Repo guidelines disallow adding code comments unless explicitly requested. Please move this rationale to a ticket/PR description and keep the constants file comment-free.

🧹 Proposed cleanup
-  // DISABLED: Tron deposits are built as simple TRC20 transfers instead of depositErc20() vault calls,
-  // and the Relay indexer notification is never sent for non-EVM chains. This causes deposits to be
-  // untracked by Relay, resulting in stuck/lost funds. Re-enable once the Tron transaction building
-  // is verified to use the Relay quote calldata (depositErc20) correctly.
-  // [tronChainId]: 728126428,
As per coding guidelines: Never add code comments unless explicitly requested.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// DISABLED: Tron deposits are built as simple TRC20 transfers instead of depositErc20() vault calls,
// and the Relay indexer notification is never sent for non-EVM chains. This causes deposits to be
// untracked by Relay, resulting in stuck/lost funds. Re-enable once the Tron transaction building
// is verified to use the Relay quote calldata (depositErc20) correctly.
// [tronChainId]: 728126428,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/swapper/src/swappers/RelaySwapper/constant.ts` around lines 89 - 93,
Remove the inline “DISABLED” explanatory comment block in constant.ts that
precedes the commented-out [tronChainId]: 728126428 entry; the file should not
contain rationale comments—only keep the actual constants (or the commented-out
key if you must leave it disabled) and move the explanatory text to the
PR/ticket description or changelog. Locate the block around the tronChainId
symbol in RelaySwapper/constant.ts and delete the multi-line rationale, ensuring
the file remains comment-free per repo guidelines.

[monadChainId]: monad.id,
[hyperEvmChainId]: hyperEvm.id,
[mantleChainId]: mantle.id,
Expand Down
4 changes: 2 additions & 2 deletions packages/swapper/src/swappers/RelaySwapper/endpoints.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { evm, isEvmChainId } from '@shapeshiftoss/chain-adapters'
import { evm } from '@shapeshiftoss/chain-adapters'
import { TxStatus } from '@shapeshiftoss/unchained-client'
import BigNumber from 'bignumber.js'

Expand Down Expand Up @@ -200,7 +200,7 @@ export const relayApi: SwapperApi = {
if (
swap.metadata.relayTransactionMetadata &&
!txIndexingMap.has(swap.id) &&
isEvmChainId(chainId)
chainIdToRelayChainId[chainId] !== undefined
) {
const relayTxParam = {
...swap.metadata.relayTransactionMetadata,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -653,12 +653,13 @@ export async function getTrade<T extends 'quote' | 'rate'>({

if (isRelayQuoteTronItemData(selectedItem.data)) {
return {
allowanceContract: '',
allowanceContract: selectedItem.data?.parameter?.contract_address ?? '',
solanaTransactionMetadata: undefined,
relayTransactionMetadata: {
relayId: quote.steps[0].requestId,
orderId,
to: selectedItem.data?.parameter?.contract_address,
data: selectedItem.data?.parameter?.data,
},
Comment on lines 654 to 663
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fail fast if Relay Tron calldata or vault address is missing.

parameter.contract_address/parameter.data are optional-chained and defaulted to ''. If the Relay response is malformed, this produces incomplete metadata and getUnsignedTronTransaction can fall back to a simple TRC20 transfer—the stuck-funds path this PR is fixing. Treat missing fields as a hard error and remove the empty-string fallback.

✅ Suggested validation
       if (isRelayQuoteTronItemData(selectedItem.data)) {
+        const contractAddress = selectedItem.data?.parameter?.contract_address
+        const calldata = selectedItem.data?.parameter?.data
+        if (!contractAddress) throw new Error('Relay Tron quote missing contract_address')
+        if (!calldata) throw new Error('Relay Tron quote missing calldata')
         return {
-          allowanceContract: selectedItem.data?.parameter?.contract_address ?? '',
+          allowanceContract: contractAddress,
           solanaTransactionMetadata: undefined,
           relayTransactionMetadata: {
             relayId: quote.steps[0].requestId,
             orderId,
-            to: selectedItem.data?.parameter?.contract_address,
-            data: selectedItem.data?.parameter?.data,
+            to: contractAddress,
+            data: calldata,
           },
         }
       }
As per coding guidelines: ALWAYS validate inputs before processing with clear validation error messages and use early returns for validation failures.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/swapper/src/swappers/RelaySwapper/utils/getTrade.ts` around lines
654 - 663, The code currently defaults missing Relay Tron calldata or vault
address to empty strings which can lead getUnsignedTronTransaction to mis-handle
the quote; update the isRelayQuoteTronItemData branch to validate that
selectedItem.data.parameter.contract_address and
selectedItem.data.parameter.data are present and non-empty, and if either is
missing return/throw a clear validation error (do not fallback to ''), then
populate relayTransactionMetadata and allowanceContract using the validated
values; reference isRelayQuoteTronItemData,
selectedItem.data.parameter.contract_address, selectedItem.data.parameter.data,
and getUnsignedTronTransaction when making the change.

}
}
Expand Down
16 changes: 16 additions & 0 deletions packages/swapper/src/tron-utils/getUnsignedTronTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@ export const getUnsignedTronTransaction = ({
})
}

if (relayTransactionMetadata?.data) {
const to = relayTransactionMetadata.to
if (!to) throw new Error('Missing Relay transaction destination address')

const isNativeTron = sellAsset.assetId === tronAssetId
const value = isNativeTron ? step.sellAmountIncludingProtocolFeesCryptoBaseUnit : '0'

return adapter.buildCustomApiTx({
from,
to,
accountNumber,
data: relayTransactionMetadata.data,
value,
})
}
Comment on lines +49 to +63
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use a custom error class for the new Relay guard.

The new guard throws a generic Error. Please switch to a custom error class from @shapeshiftoss/errors (or propagate via the existing Result flow) so error codes remain consistent and i18n-ready.

As per coding guidelines: ALWAYS use custom error classes from @shapeshiftoss/errors with meaningful error codes for internationalization and relevant details in error objects.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/swapper/src/tron-utils/getUnsignedTronTransaction.ts` around lines
49 - 63, The guard in getUnsignedTronTransaction currently throws a generic
Error when relayTransactionMetadata.to is missing; replace that with a custom
error from `@shapeshiftoss/errors` (import the appropriate error class/function)
and throw a namespaced/i18n-ready error (e.g., code "RELAY_MISSING_TO") instead
of new Error('Missing Relay transaction destination address'), including
relevant context (relayTransactionMetadata, sellAsset, step or from) in the
error details to aid debugging while preserving the function return flow.


const to = relayTransactionMetadata?.to ?? nearIntentsSpecific?.depositAddress
if (!to) throw new Error('Missing transaction destination address')

Expand Down
Loading