Skip to content

Rango: Add Tron swap support - #484

Open
j0ntz wants to merge 2 commits into
masterfrom
jon/rango-tron-contract-call
Open

Rango: Add Tron swap support#484
j0ntz wants to merge 2 commits into
masterfrom
jon/rango-tron-contract-call

Conversation

@j0ntz

@j0ntz j0ntz commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

Needs edge-currency-accountbased Tron contract-call support to execute (PR linked in the description).

Description

Asana: https://app.asana.com/0/1215088146871429/1216839790397157

tron -> TRON has been in the Rango mapping all along, so TRON quotes were already being
requested. Building the transaction was the missing half: tx.type === 'TRON' fell into the
default: branch, which runs asEvmTransaction(tx) and throws.

What changed

  • asTronTransaction reads Rango's raw_data (and approve_raw_data) as a
    TriggerSmartContract payload. Every level uses .withRest, so nothing the provider sent is
    dropped before it reaches the currency plugin: parameter.type_url is serialized into the
    signed raw data, so losing it would change the transaction.
  • The TRON case builds a spendInfo carrying { contractJson, feeLimit } in otherParams
    and targeting the router address. A TRC20 sell also needs an allowance, which Rango returns
    inline as approve_raw_data; that becomes a tokenApproval pre-transaction, the same shape
    the EVM path already uses.
  • Provider payloads are bound to the quote before anything is signed: the swap's call_value
    may not exceed the quoted amount (native TRX) or be nonzero (TRC20), and the approval must
    grant the swap router, over the sold token, no more than the quoted sell amount, with no TRX
    attached. The swap itself may not call the sold token contract or use a transfer/approve
    selector, so the bounded approval is the only call that touches the token directly. Neither call may
    attach a TRC10 balance (call_token_value).
  • hexToTronAddress converts the hex addresses in a contract payload to the base58check form
    wallets and spend targets speak.

Rango API key as apikey

Rango is deprecating its old way of passing the API key and asked for the apikey query
parameter. makeRangoAuthParams puts the key in both apikey and the legacy apiKey, used by
basic/swap and the mapctl synchronizer's basic/meta. Sending only apikey is not possible
yet: against api.rango.exchange, apikey alone returns 401, apiKey alone 200, and both
together 200.

Testing

Unit tests cover the address conversion against the USDT contract, the Sun Swap router, and an
owner address.

Driven against the live Rango API with stub wallets: a native TRX sell produces one swap
spendInfo with call_value set and no approval; a USDT sell produces the 095ea7b3 approval
pre-transaction followed by the swap.

Then end to end on the iOS sim with edge-currency-accountbased#1088
linked in: a TRX → USDT swap through Rango reached the success scene, and on-chain
42fd4970…9650
is a TriggerSmartContract with contractRet: SUCCESS, selector cef95229 against the Sun Swap
router, delivering 13.004043 USDT in the same transaction. Screenshots in a comment below.

For the apikey change and the payload guards, with this branch's bundle and
edge-currency-accountbased#1088's copied into the installed app:

  • A unit test asserts both key parameters reach the query string, and a live drive of the real
    plugin showed basic/swap returning 200 with apikey and apiKey in the query and no key
    header.
  • 3.001 USDC → 32.40 POL on Polygon through Rango reached the success scene.
  • 14.709 TRX → 5.007 USDT through Rango: 73d275c5…,
    TriggerSmartContract SUCCESS, selector cef95229, call_value 14709000 (the quoted amount).
  • 5.002 USDT → 14.714 TRX through Rango, the TRC20 sell: approval
    60e0b6e4…
    grants exactly 5002000 to the Sun Swap router with call_value 0, then swap
    87785e37…,
    both SUCCESS.
  • On the final build (TRC10 guard included): 3.001 USDT → 8.926 TRX, approval
    1f6f4b0e…
    granting exactly 3001000, swap
    d44d1e67…,
    both SUCCESS.

Note

Medium Risk
Adds a new on-chain swap execution path with TRC20 approvals; validation mitigates wrong-spender approvals, but execution still depends on companion Tron contract-call support in the currency plugin.

Overview
Rango TRON swaps no longer hit the EVM default branch and fail parsing. Responses with tx.type === 'TRON' are validated and turned into wallet spends that pass Rango’s TriggerSmartContract payload through to the Tron currency plugin via otherParams.contractJson and feeLimit.

For TRC20 sells, when Rango includes approve_raw_data, the plugin queues a tokenApproval pre-transaction (same pattern as EVM). It decodes the approval spender from call data and rejects approvals that don’t target the swap router or the token being sold.

Address helpers hexToTronAddress and decodeTronApprovalSpender convert hex contract addresses to base58 and parse approve() calldata; unit tests cover known contracts and error cases.

Reviewed by Cursor Bugbot for commit bcccdb3. Bugbot is set up for automated code reviews on this repo. Configure here.

@j0ntz

j0ntz commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

📸 Test evidence: Rango TRX → USDT swap on iOS sim

rango trx usdt quote

rango trx usdt quote

rango trx swap success

rango trx swap success

rango trx tx details

rango trx tx details

Captured by the agent's in-app test run (build-and-test).

@j0ntz
j0ntz force-pushed the jon/rango-tron-contract-call branch from 49ca31d to dc41dc5 Compare August 14, 2026 17:24
@j0ntz
j0ntz marked this pull request as ready for review August 14, 2026 17:24
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

Comment thread src/swap/defi/rango.ts
@j0ntz
j0ntz force-pushed the jon/rango-tron-contract-call branch from dc41dc5 to bcccdb3 Compare August 14, 2026 17:38
@j0ntz

j0ntz commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

📸 Test evidence (apikey query param)

rango usdc pol quote

rango usdc pol quote

rango usdc pol swap success

rango usdc pol swap success

rango usdc pol tx details

rango usdc pol tx details

Captured by the agent's in-app test run (build-and-test).

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

Agentic security review found two issues in the new Rango TRON path: unbounded provider approval amounts (HIGH) and unsigned call_value vs quoted nativeAmount (MEDIUM). The earlier spender-mismatch thread remains addressed.

Open in Web View Automation 

Sent by Cursor Security Agent: Security Reviewer

Comment thread src/swap/defi/rango.ts
Comment thread src/swap/defi/rango.ts
@j0ntz
j0ntz force-pushed the jon/rango-tron-contract-call branch from 2abfbd5 to 85efab4 Compare September 10, 2026 21:48

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread src/swap/defi/rango.ts Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

Comment thread src/swap/defi/rango.ts
@j0ntz
j0ntz force-pushed the jon/rango-tron-contract-call branch from 85efab4 to 407fb33 Compare September 10, 2026 22:04

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale comment

Agentic security review found one remaining high-severity issue on the TRON swap path: provider swap calldata is still not bound to the quoted sell after the sold-token and selector checks. Approval amount and call_value guards do not cover an omitted-approval router pull against an existing allowance, or increaseApproval on a token other than the asset being sold.

Open in Web View Automation 

Sent by Cursor Security Agent: Security Reviewer

Comment thread src/swap/defi/rango.ts
@j0ntz
j0ntz force-pushed the jon/rango-tron-contract-call branch 2 times, most recently from a937ff0 to a89a728 Compare September 10, 2026 22:32

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a89a728. Configure here.

Comment thread src/swap/defi/rango.ts
@j0ntz

j0ntz commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

Correction to the "Test evidence (apikey query param)" comment above: that Polygon swap ran the published edge-exchange-plugins 2.55.0, not this branch. The iOS build's npm install reverted the local link before the bundle was embedded. The comment below replaces it: the branch's own bundles were copied into the installed app (verified by literals only this branch contains), and the same USDC to POL swap plus both TRON directions were executed on it.

@j0ntz

j0ntz commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

📸 Test evidence (branch bundles: apikey + TRON both directions)

rango usdc pol quote branch

rango usdc pol quote branch

rango usdc pol swap success branch

rango usdc pol swap success branch

rango trx usdt quote

rango trx usdt quote

rango trx usdt swap success

rango trx usdt swap success

rango usdt trx quote

rango usdt trx quote

rango usdt trx swap success

rango usdt trx swap success

Captured by the agent's in-app test run (build-and-test).

A TRON quote fell through to the EVM transaction handler and threw,
even though the chain was already mapped. Build the spend from the
TriggerSmartContract call Rango returns, passing it to the currency
plugin intact, and turn the router allowance Rango returns alongside a
TRC20 sell into a pre-transaction.
Rango is deprecating its old way of passing the API key and asked for the `apikey` query parameter. Its API still answers 401 to `apikey` alone and 200 when the legacy `apiKey` parameter rides with it, so both are sent until the lowercase name is accepted on its own.
@j0ntz
j0ntz force-pushed the jon/rango-tron-contract-call branch from a89a728 to 8dd52d9 Compare September 11, 2026 17:20

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Agentic security review of the Rango TRON path found one remaining high-severity issue: provider fee_limit is copied unbounded onto the signed spend while the displayed network fee uses the energy estimate (or a small fallback). Prior findings on this PR were already addressed.

Open in Web View Automation 

Sent by Cursor Security Agent: Security Reviewer

Comment thread src/swap/defi/rango.ts
@j0ntz

j0ntz commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

📸 Test evidence (final build: USDT to TRX with approval)

rango usdt trx quote final

rango usdt trx quote final

rango usdt trx swap success final

rango usdt trx swap success final

Captured by the agent's in-app test run (build-and-test).

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.

1 participant