Skip to main content
By default, CCTP Fast Transfer and Forwarding Service fees are taken from the amount minted on the destination chain. You can instead pay those fees upfront on the source chain so the recipient receives the exact bridge amount. For how this fits into the overall fee model, see How bridge fees work.

Prerequisites

Before you begin, ensure that you’ve: These are required so any example below runs with a valid kit and adapter.

Estimate and bridge with source-paid fees

This example estimates, then bridges 1.00 USDC from Ethereum Sepolia to Arc Testnet. The recipient is credited the exact amount; the source wallet pays amount plus the quoted fee. Source-paid fees use a two-step flow:
  1. Call estimateBridge with feePayment: "source". The result includes a quote — a signed, time-bound fee quote from Circle’s Fee Service.
  2. Call bridge with the same transfer parameters and that quote. The SDK submits the burn with the quote so the fee is collected on the source chain and the destination mint stays unreduced.
TypeScript
When feePayment is "source", TypeScript narrows the estimate as ReceiveExactEstimateResult (no cast or in narrowing needed). Without feePayment: "source", the return type remains the plain estimate result.
quote is the Fee Service’s raw signed quote: a 0x-prefixed, byte-aligned hex string. Treat it as opaque — do not decode, edit, or reconstruct it. Pass it through unchanged.When you pass quote, Bridge Kit validates that exact quote before and after approval and fails closed if it is invalid, mismatched, expired, or too close to expiry. It never silently replaces a caller-supplied quote. Omitting quote opts into SDK-managed fetching and refresh. On a supplied-quote failure, call estimateBridge() again and retry with the new quote.
A successful estimate looks like this (values vary by route and quote):
TypeScript
fees is the familiar estimate breakdown (forwarder / provider). feeItems is the signed Fee Service line items (FORWARD, PRE_FINALITY) that back the upfront quote. Step events (bridge.approve, bridge.burn, bridge.mint, and others) fire on this path the same way as other bridge transfers. See Bridge events in the SDK reference.

Check which chains support source fees

Not every bridge source supports paying fees on the source chain. List the ones that do:
TypeScript

Requirements and limitations

Forwarding Service is required

to.useForwarder: true is required with feePayment: "source". Omitting it (or setting it to false) throws a validation error.

Custom fees are not supported

You cannot combine feePayment: "source" with a per-call config.customFee or a kit-level custom fee policy (setCustomFeePolicy). The SDK throws by design. Collect custom bridge fees only on the default (destination) fee path.

Use SLOW on Standard Transfer–only sources

transferSpeed defaults to FAST. Some source chains support only CCTP Standard Transfer (for example Avalanche, Polygon PoS, Sei, XDC, and their testnets). On those chains, keep feePayment: "source" and set transferSpeed: "SLOW". Using FAST (or omitting transferSpeed) can fail with a Quote API error such as PRE_FINALITY_UNAVAILABLE (often surfaced as HTTP 422).
TypeScript

Error results can preserve a successful burn

If the burn confirms but the Forwarding Service / relayer returns no destination transaction hash, the SDK returns an error-state BridgeResult that still includes the burn step (retryable), instead of throwing away that progress. See Error recovery for how to inspect result.state and result.steps.