Skip to main content
A withdrawal spends USDC from the owner’s Stellar wallet and delivers it to an EVM address the user types. The user signs Stellar transactions only; Pesa pays the Stellar fees and the destination-chain gas.

CCTP: USDC to an EVM chain

1

Quote with the destination

An invalid address for the chain is refused here, before any signature.
2

Prompt 1: approve

Circle’s Stellar minter moves USDC with transfer_from, so it needs an allowance. If an allowance already covers the amount, this prompt is skipped.
3

Prompt 2: burn

4

Delivery

Iris attests the burn, and Pesa’s relayer calls receiveMessage on Arbitrum. The status becomes completed when the mint is observed there.
The amount is floored to 6 decimals for CCTP. The 7th decimal stays in the wallet. If the allowance expires between the two prompts (it lasts about a day), the transfer returns to AWAITING_SIGNATURE and asks for prompt 1 again.

USDT0: USDC to USDT on an EVM chain

Use route: "usdt0-withdraw". Pesa first tops up the XLM the LayerZero fee needs (stage FUNDED, status pending_anchor). Then:
  1. Prompt 1: the USDC to USDT0 swap. Check it with verifyStellarSwap.
  2. Prompt 2: the OFT send to the destination chain. Check it with verifyStellarOftSend.
If the user stops after the swap, the transfer expires after 24 hours and the USDT0 stays in their wallet. Withdrawals to Ethereum through USDT0 are refused because the LayerZero fee is above the cap.

Always pass what the user typed

The withdrawal address in verifyStellarBurn and verifyStellarOftSend must come from your UI. These two verifiers are the last check that the funds go where the user asked.