Overview
The IrisClient provides methods for fetching attestations from Circle’s Iris API, which is required to complete cross-chain USDC transfers. After burning USDC on the source chain, you must obtain an attestation from Iris before minting on the destination chain.
IrisClient Type
type IrisClient struct {
baseURL string
httpClient * http . Client
}
Base URL for the Iris API (mainnet or testnet)
HTTP client with 30-second timeout
Creating a Client
func NewIrisClient ( baseURL string ) * IrisClient
client := cctp . NewIrisClient ( "https://iris-api.circle.com" )
client := cctp . NewIrisClient ( "https://iris-api-sandbox.circle.com" )
Core Methods
GetMessages
Fetch messages and attestations for a specific transaction:
func ( c * IrisClient ) GetMessages (
ctx context . Context ,
sourceDomain uint32 ,
txHash string ,
) ( * MessagesResponse , error )
Context for cancellation and timeout
CCTP domain of the source chain
Transaction hash of the burn transaction
Example
Response Structure
resp , err := client . GetMessages (
ctx ,
0 , // Ethereum domain
"0x1234..." ,
)
if err != nil {
log . Fatal ( err )
}
if len ( resp . Messages ) > 0 {
msg := resp . Messages [ 0 ]
fmt . Printf ( "Status: %s \n " , msg . Status )
fmt . Printf ( "Attestation: %s \n " , msg . Attestation )
}
PollForAttestation
Poll for an attestation until it’s ready or context is cancelled:
func ( c * IrisClient ) PollForAttestation (
ctx context . Context ,
sourceDomain uint32 ,
txHash string ,
progressCallback func ( attempt int , elapsed time . Duration ),
) ( * Message , error )
Context for cancellation and timeout
CCTP domain of the source chain
Transaction hash of the burn transaction
Optional callback invoked on each polling attempt
Basic Usage
With Progress Tracking
With Timeout
msg , err := client . PollForAttestation (
ctx ,
0 , // Ethereum
burnTxHash ,
nil , // No progress callback
)
if err != nil {
log . Fatal ( err )
}
fmt . Printf ( "Attestation received: %s \n " , msg . Attestation )
The polling function implements exponential backoff (2s → 4s → 8s → 10s max) and handles transient 404 errors during indexing.
GetTransferFees
Query fee information for transfers between domains:
func ( c * IrisClient ) GetTransferFees (
ctx context . Context ,
sourceDomain uint32 ,
destDomain uint32 ,
) ( * FeesResponse , error )
Context for cancellation and timeout
Destination chain CCTP domain
Example
Response Structure
feesResp , err := client . GetTransferFees (
ctx ,
0 , // Ethereum
1 , // Avalanche
)
if err != nil {
log . Fatal ( err )
}
for _ , feeInfo := range feesResp . Data {
fmt . Printf ( "Threshold %d : %d bps \n " ,
feeInfo . FinalityThreshold ,
feeInfo . MinimumFee ,
)
}
Fees are returned in basis points (bps). For example, 14 bps = 0.14% fee.
Attestation Status
Attestation status indicates whether an attestation is ready:
type AttestationStatus string
const (
AttestationStatusPending AttestationStatus = "pending"
AttestationStatusComplete AttestationStatus = "complete"
)
Error Handling
The Iris API enforces rate limits. A 429 status code indicates rate limiting.
msg , err := client . GetMessages ( ctx , domain , txHash )
if err != nil {
if strings . Contains ( err . Error (), "429" ) {
log . Println ( "Rate limited - wait 5 minutes before retrying" )
}
return err
}
Estimated Attestation Times
Helper function to estimate attestation time based on chain characteristics:
func EstimatedAttestationTime ( instantFinality bool ) time . Duration
// For instant finality chains (Avalanche, Polygon, etc.)
if sourceChain . InstantFinality {
estimate := cctp . EstimatedAttestationTime ( true )
fmt . Printf ( "Expected attestation in ~ %s \n " , estimate ) // ~10 seconds
}
// For standard EVM chains
estimate := cctp . EstimatedAttestationTime ( false )
fmt . Printf ( "Expected attestation in ~ %s \n " , estimate ) // ~15 seconds for Fast Transfer
Best Practices
Use Context Timeouts
Always set reasonable timeouts to prevent indefinite waiting: ctx , cancel := context . WithTimeout ( context . Background (), 5 * time . Minute )
defer cancel ()
Handle 404 Errors
The API may return 404 immediately after a burn transaction while indexing. The PollForAttestation function handles this automatically.
Check Attestation Status
Verify that msg.Status == AttestationStatusComplete and msg.Attestation != "" before proceeding to mint.
Implement Retry Logic
Handle transient network errors with exponential backoff: for attempt := 1 ; attempt <= 3 ; attempt ++ {
msg , err := client . GetMessages ( ctx , domain , txHash )
if err == nil {
break
}
time . Sleep ( time . Duration ( attempt ) * time . Second )
}
Next Steps
Transfer Orchestrator See how IrisClient is used in the complete transfer flow
Contract Bindings Use attestations with MessageTransmitterV2