Skip to main content

Overview

CashmereCCTP wraps Circle’s CCTP on every supported chain: the contract takes Cashmere’s fee, burns the USDC through Circle and emits a CashmereTransfer event. Cashmere’s relayers then mint on the destination chain, so a transfer is a single source-chain transaction.
Most integrations don’t need this page. The Cashmere Agent SDK builds and sends every transaction below (cctp.transfer()), and its MCP server exposes them to AI agents. Read on to call the contracts yourself; the SDK’s src/chains/*.ts is a tested reference implementation of each flow.
Use CCTP V2. Circle cuts V1 burn limits from 31 Oct 2026 and stops V1 burns on 1 Dec 2026. Every route has V2, Aptos and Sui included since 26 Oct 2026. The V1 entry points are listed for reference only.
Contract Repository: GitHub - cashmere-prod/contracts-prod. Addresses for every chain are on Contract Addresses.

Entry Points

From Quote to Call

Every transfer carries a quote signed by the Cashmere Gas API. The quote’s fee and deadline are part of the signed message, so pass them exactly as returned: any other value fails the signature check.
  1. Get a quote for the route (Backend APIs):
    • EVM sources: GET https://gas.cashmere.exchange/getEcdsaSig_native?localDomain=6&destinationDomain=3&isNative=true&isV2=true
    • Solana, Aptos and Sui sources: GET https://gas.cashmere.exchange/getEd25519Sig_native?localDomain=9&destinationDomain=6&isNative=true&version=2
  2. Get Circle’s fee for the finality threshold: GET https://iris-api.circle.com/v2/burn/USDC/fees/6/3 returns an array of finalityThreshold and minimumFee (basis points, possibly fractional, such as 1.3).
  3. Call the V2 entry point with these values:
What arrives. The contract takes amount × feeBP / 10000 from the USDC (feeBP is 0 today, at most 100, that is 1%), plus the quoted fee when isNative is false. On V2 Fast, Circle keeps up to maxFee when it mints. The recipient gets the rest.

Signed Payloads

The Gas API signs the same fields on every chain: local domain, destination domain, fee, deadline, isNative and the CCTP version. A V1 signature therefore never passes a V2 entry point, and the other way round. EVM checks an ECDSA signature over the raw digest (no \x19Ethereum Signed Message prefix):
Solana checks an Ed25519 signature over the Borsh encoding below, through an Ed25519 program instruction placed before the transfer instruction. Always request Solana quotes with version=1 or version=2: without it the message has no version byte and the program rejects it (InvalidMessageData).
Aptos and Sui check an Ed25519 signature over the BCS encoding of TransferParamsV2 (TransferParams without cctp_version for V1). Request their quotes with version=2.
On the Ed25519 endpoint the message field of the quote is exactly these bytes, and publicKey is the signer key that the contracts store.

Recipient Encoding

Every chain takes the recipient as 32 bytes, and CCTP mints to whatever account those bytes name. An address in the wrong format doesn’t revert: the USDC arrives at an account nobody controls. The SDK’s recipientError(to, recipient) checks a recipient before you sign.
  • To an EVM chain: the 20-byte address, left-padded to 32 bytes (ethers.zeroPadValue(address, 32)).
  • To Solana (domain 5): recipient is the wallet’s USDC associated token account (ATA) and solanaOwner is the wallet itself, both as 32-byte hex. Cashmere’s relayers create the ATA if it doesn’t exist yet.
  • To Aptos or Sui: the 32-byte account address (0x and 64 hex characters). An EVM address padded to 32 bytes is not an Aptos or Sui account.
  • solanaOwner is 32 zero bytes for every destination other than Solana.

EVM Implementation

Interface

TransferV2

TransferV2WithPermit

Skip the approval transaction with an EIP-2612 permit for the same amount:

Security Features

  • Reentrancy: a lock flag in the contract state guards every transfer and fee withdrawal.
  • Signed quotes: the fee, deadline, route and version are signed by the Cashmere signer and checked on chain.
  • Fee cap: the percentage fee is at most 100 basis points (1%); it is 0 today.
  • Pause: the admin can pause transfers.

Solana Implementation

Program ID 5RsvKL6LFq6yEFiAXEwgYHAN3aLFypeB4AaafdeDnHqM, domain 5. Account addresses, the address lookup table and the CCTP program IDs are on Contract Addresses.
The transaction needs three instructions in this order: a compute budget, the Ed25519 verification of the quote, and transfer_v2. transfer_v2 also needs a fresh keypair that signs as messageSentEventData, where Circle stores the burn message.

Aptos Implementation

Module 0xe49afb1896889e3e1dd7bcbb9e31d1df8221899d3d368e98588ac6b4d84b136d::transfer, domain 9. Aptos sends V2 Norm (min_finality_threshold = 2000).
The module withdraws usdc_amount and burns it minus the USDC fee.

Sui Implementation

Calls go to the upgraded package 0x7eab670b3f3e3bb7a0451c7c6b6b627c09e282f0c78eac24966f6479c649d0d5; its types keep the original package ID 0xdf37112aacb7d3535f7b3b754b9a7b9fa1a6b3a756288dc734522c603c6f11a4. Domain 8. Sui sends V2 Norm (min_finality_threshold = 2000).
V2 runs Circle’s package-auth flow in one transaction: Cashmere takes its fee and returns a ticket, TokenMessengerMinter V2 turns it into a burn receipt, the USDC handler burns the coin, and complete_burn sends the message. The ticket and receipts can’t be stored or dropped, so the four calls must share a transaction.
client is a SuiGrpcClient from @mysten/sui/grpc: Sui fullnodes no longer serve JSON-RPC.

Domain IDs

Circle CCTP domain IDs differ from chain IDs. Use them in every Gas API request and contract call. Every chain can send V2 Norm to every other chain, and receive V2 Fast from the Fast sources.

Chain IDs

Error Codes

EVM

BPTooHigh(), ZeroLimit(), WithdrawCooldownNotPassed() and WithdrawLimitExceeded() come from admin functions.

Solana

Anchor numbers each error enum from 6000, so the same code can mean different errors: identify them by name in the transaction logs.

Aptos and Sui

Events

Every chain emits a CashmereTransfer event with the same fields, which Cashmere’s relayers and indexers read:

Admin Functions

Integrators never call these: they set the fee, the signer, the gas-drop limits and the pause flag, and withdraw collected fees. On EVM they are restricted to DEFAULT_ADMIN_ROLE (setFeeBP, setSigner, setMaxUSDCGasDrop, setMaxNativeGasDrop, setPaused, withdrawFee); Solana, Aptos and Sui have the equivalent owner-only instructions.

Best Practices

  1. Use V2 entry points on every route.
  2. Pass the quote’s fee and deadline unchanged, and request a new quote if the deadline is close.
  3. Check the recipient format for the destination chain before signing.
  4. Take maxFee from Circle Iris for the threshold you send.
  5. Report a transfer only once its transaction is confirmed, and keep the transaction hash: delivery on the destination chain is automatic.
  6. Use permits on EVM to skip the approval transaction.

View Source Code

Browse the contract repository