Skip to main content
Once you have established a unified USDC balance in a smart contract account (SCA), you can transfer it instantly to any supported destination chain using ERC-1271. The SCA authorizes the transfer with its own signature—no delegate Externally Owned Account (EOA) required. This guide demonstrates how to transfer your unified balance with a Circle Smart Contract Account (SCA) wallet. For the EOA path, see Transfer a unified USDC balance.
This example uses Circle SCA wallets but the Gateway request is the same for any ERC-1271 wallet. Only signing differs: obtain opaque signature bytes that make isValidSignature return 0x1626ba7e, then POST { burnIntent, signature, contractSigner: true }. Do not split the signature into v, r, s.
Nanopayments and x402 batch settlement do not support ERC-1271. See ERC-1271 programmable authorization.

Prerequisites

Before you begin, ensure that you’ve:
  • Installed Node.js v22.6+
  • Created a Circle Console account
  • Obtained an API key and registered your Entity Secret
  • Created SCA wallets via Circle developer-controlled wallets on the source and destination chains (this guide uses Arc Testnet and Base Sepolia)
    • The source SCA holds your Gateway USDC deposits and signs burn intents
    • The destination wallet submits the mint (can be the same address on another blockchain)
  • Deposited USDC into the Gateway Wallet from your SCA on Arc Testnet and waited for the deposit to finalize
  • Created a TypeScript project with the Developer-Controlled Wallets SDK installed
  • Set up a .env file with the following variables:
    .env

Steps

Follow these steps to transfer a unified USDC balance from an SCA. This example transfers 1 USDC from Arc Testnet to Base Sepolia. You can adapt it for any blockchains where you hold a unified balance.

Step 1. Create and sign the burn intent with the SCA

Create a new file called transfer.ts in the root of your project and add the following code to it. This code creates a burn intent for 1 USDC on Arc Testnet and signs it with your SCA. Set sourceDepositor and sourceSigner to the SCA address.
transfer.ts
For production apps, verifying the balance on each blockchain before creating burn intents is best practice. For this how-to, it’s assumed that the balances are created per the prerequisites. For a complete end-to-end example that includes checking and error handling, see the Gateway quickstarts (EVM, Solana).

Step 2. Submit the burn intent to the Gateway API to obtain an attestation

Add the following code to transfer.ts. This code constructs a Gateway API request to the /transfer endpoint with contractSigner: true so Gateway validates the signature with ERC-1271, and obtains the attestation from that endpoint.
transfer.ts
When contractSigner is true, Gateway validates via ERC-1271 on sourceSigner. When omitted or false, it expects an EOA ECDSA signature. See Use ERC-1271 validation.

Step 3. Transfer USDC to the destination chain

Add the following code to transfer.ts. This code performs a call to the Gateway Minter contract on Base Sepolia to instantly mint the USDC to your recipient wallet on that blockchain.
transfer.ts
RECIPIENT_ADDRESS must be a destination chain developer-controlled wallet in your Circle account. The script uses createContractExecutionTransaction() to submit gatewayMint().

Step 4. Run the script

Run the script with the following command:
ERC-1271 validation runs offchain as a read-only simulation. Authorization logic that modifies onchain state during validation isn’t supported. See ERC-1271 programmable authorization for the full list of limitations.