Tron
USDT on Tron is the biggest stablecoin float in the corridors Corridor serves, and nothing carries it to Stellar in one move. The solver network will not quote Stellar in either direction; CCTP has no Tron domain. So the lane is two hops, and the interesting part is what happens between them.
The route
Section titled “The route”Tron USDT → Solana USDC
planTronDeposit takes a live quote from NEAR Intents 1Click and returns a one-off Tron address to hand the user. The quote fixes the amount, the recipient and the refund address before anything is sent.
Solana USDC → Stellar USDC
tronBurnLeg burns what actually arrived, and cctp.transfer waits for Circle’s attestation and completes the mint on the hub. That half is the CCTP lane already in place.
Who owns the money in between
Section titled “Who owns the money in between”Somebody has to own the USDC on Solana and sign the burn. If that were Corridor, this would be custody.
It is the user. A Stellar account and a Solana address are the same 32-byte Ed25519 key written two ways — StrKey for Stellar, base58 for Solana — so a user holding one key already has an account on both chains:
import { solanaAddressOfStellar } from "@corridor/bridge-cctp";
solanaAddressOfStellar("GB3GBC2AGV2BIWWK5LCDW5EHGXVIBRROWJJT44VYENLAM7L65F6LJ6UY");// "8y6VZ5L8aQHVSpf2NhW8soP9yKM14HuFpqPqyAuoAUgB" — same key, same personThe swap pays out there, and the burn is signed with that key by the app’s wallet. Corridor’s only contribution is gas: an address derived this way starts with no SOL, so a Corridor vault signs the burn as fee payer while the user signs as owner. Corridor pays for the move and cannot make it. See ADR 0015.
Quoting
Section titled “Quoting”A dry quote prices the lane without reserving anything, which is what a rate in a UI should use:
const rate = await quoteTronDeposit({ oneClick, stellarAccount, // the user's G… account amount: 150_000_000n, // USDT, Tron's 6 decimals refundTo: tronAddress, // the user's own Tron address});The solver network refuses anything under $100, a floor it describes as temporary. Corridor checks it before calling out so a smaller deposit gets a usable answer, and when the floor moves it passes the server’s own wording through rather than substituting a stale constant.
When it goes wrong
Section titled “When it goes wrong”The two failure modes are not the same, and assertDelivered keeps them apart:
| State | What it means | What Corridor does |
|---|---|---|
SUCCESS |
Delivered, with an amount and a Solana payout | Burn that amount onward |
REFUNDED |
The USDT went back to the user’s Tron address | The deposit is over. No retry — re-quoting would price money that has gone |
FAILED |
No solver filled it | No retry |
INCOMPLETE_DEPOSIT |
Less arrived than the quote priced; the solver holds it, filling nothing and refunding nothing | manual_review — only a person can decide |
A SUCCESS missing its amount or its payout transaction also goes to review rather than being booked as a delivery nobody can point at.
Through the Ramp API
Section titled “Through the Ramp API”# What it would deliver, reserving nothingcurl -X POST $RAMP/v1/deposits/tron/quotes -H "authorization: Bearer $KEY" \ -d '{"account":"GB3G…","amount":"150000000","refundTo":"TJRy…"}'
# Open one: returns the Tron address to send USDT tocurl -X POST $RAMP/v1/deposits/tron -H "authorization: Bearer $KEY" \ -d '{"account":"GB3G…","amount":"150000000","refundTo":"TJRy…"}'{ "id": "td_01JD…", "depositAddress": "TWd4JxMVfwRTqtPEAjNRMBXvAUPuTqy4tL", "tronAmount": "150000000", "expectedUsdc": "149767242", "minUsdc": "148269569", "solanaAddress": "8y6VZ5L8aQHVSpf2NhW8soP9yKM14HuFpqPqyAuoAUgB", "account": "GB3G…", "status": "awaiting_deposit", "expiresAt": "2026-10-26T12:17:37.545Z"}POST returns as soon as the quote is taken. It does not wait for the solver: that wait is a minute at best and twenty at worst, so the saga is started and a ticker moves it along, exactly as webhook delivery and reconciliation are moved along. Poll GET /v1/deposits/tron/{id}, or take the tron_deposit.updated webhook.
| Status | What has happened |
|---|---|
awaiting_deposit |
The address is live; the user’s USDT has not arrived |
processing |
The swap filled; the burn and mint are running |
completed |
USDC is on the user’s Stellar account |
failed |
Refunded to the user’s Tron address, or unfillable |
manual_review |
A short deposit, or a success missing its amount or payout |
Status
Section titled “Status”Built and tested against recorded API shapes, with the quote and status endpoints verified live on 26 Oct 2026. Not yet run with real money — a first mainnet run needs $100 of USDT on Tron, which is also the smallest swap the solver network accepts. See the roadmap.