Bridging overview
The build, sign, broadcast pattern that every route shares.
Every transfer is the same three step pattern.
- Build the source chain burn tx (approve first if allowance is short).
- Wait for Circle to attest the burn.
- Build the destination chain receive tx and broadcast it.
The SDK returns each transaction as an unsigned RawTransaction. You sign and broadcast them with your wallet.
Pre flight
Discovery works without any wallet setup. Chains, tokens, quotes, balances, and allowances are all read only.
const chains = await sdk.chainDetailsMap();
const sourceToken = chains[NetworkId.BASE].tokens[0];
const destinationToken = chains[NetworkId.STELLAR].tokens[0];
const quote = await sdk.bridge.quote({ sourceToken, destinationToken });
console.log(quote.feeBps, quote.estimatedSeconds);
if (!(await sdk.bridge.hasTrustline({ token: destinationToken, address: recipient }))) {
throw new Error("Recipient must establish a USDC trustline first");
}Approve when allowance is short
const enough = await sdk.bridge.checkAllowance({
token: sourceToken,
owner: sender,
amount: "1.0",
});
if (!enough) {
const approveTx = await sdk.bridge.rawTxBuilder.approve({
token: sourceToken,
owner: sender,
});
await mySignAndBroadcast(approveTx);
}Omit the amount field to request an unlimited approval, or pass a specific value to approve exactly what you plan to burn.
Send the burn
const burnTx = await sdk.bridge.rawTxBuilder.send({
sourceToken,
destinationToken,
amount: "1.0",
fromAccountAddress: sender,
toAccountAddress: recipient,
minFinalityThreshold: FinalityThreshold.FAST,
});
const burnHash = await mySignAndBroadcast(burnTx);The SDK reads the Iris fee quote automatically and sets maxFee with a 20% safety buffer so your burn is not parked for insufficient_fee.
Wait for the attestation
Circle Iris watches the burn, waits for the finality threshold, and produces a signed message you can present on the destination chain.
const att = await sdk.attestation.waitFor(NetworkId.BASE, burnHash, {
onPoll: ({ attempt, delayReason }) => {
if (delayReason) console.log("Iris delay:", delayReason);
},
});See Attestation polling for the full contract.
Receive the mint
const mintTx = await sdk.bridge.rawTxBuilder.receive({
destinationToken,
toAccountAddress: recipient,
message: att.message,
attestation: att.attestation,
});
await mySignAndBroadcast(mintTx);That is the whole flow. Pick a route below for the per chain worked example.