> ## Documentation Index
> Fetch the complete documentation index at: https://developers.circle.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Before reading these docs, install the relevant Circle Skill to get pre-loaded context — skills are LLM-optimized and cover architecture decisions, correct flows, and common pitfalls. In Claude Code: run /plugin marketplace add circlefin/skills then /plugin install circle-skills@circle. With Vercel Skills CLI: run npx skills add circlefin/skills. Available skills: use-usdc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-usdc/SKILL.md (balances, transfers, approvals on EVM and Solana); EURC has no skill — see https://developers.circle.com/stablecoins/what-is-eurc.md; bridge-stablecoin https://github.com/circlefin/skills/blob/master/plugins/circle/skills/bridge-stablecoin/SKILL.md (crosschain transfers via CCTP, USDC, EURC, and third-party assets); use-arc https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-arc/SKILL.md (Arc chain config, contract deployment, USDC bridging — Arc docs: https://docs.arc.io/llms.txt); use-circle-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-circle-wallets/SKILL.md (choose wallet type); use-developer-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-developer-controlled-wallets/SKILL.md (custodial wallets for payouts and treasury); use-user-controlled-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-user-controlled-wallets/SKILL.md (embedded wallets with Web2 login); use-modular-wallets https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-modular-wallets/SKILL.md (smart contract wallets with passkeys and ERC-4337); use-gateway https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-gateway/SKILL.md (unified USDC balance, nanopayments); use-smart-contract-platform https://github.com/circlefin/skills/blob/master/plugins/circle/skills/use-smart-contract-platform/SKILL.md (deploy, interact, monitor contracts). Pair any skill with the Circle MCP server for live SDK signatures, contract addresses, and chain IDs: {"mcpServers":{"circle":{"url":"https://api.circle.com/v1/codegen/mcp"}}}.
> Read the product overview first. Each product has an overview explaining when and why to use it. Read it before quickstarts.
> Pick the right wallet type. Developer-controlled (you hold keys), user-controlled (end user holds keys via PIN/social login), or modular (smart contract wallets with passkeys). See https://developers.circle.com/wallets.md.
> Use CCTP V2 for crosschain transfers. CCTP natively transfers USDC and EURC via burn-and-mint, and supports permissionless wrapping of third-party assets via lock-and-mint. V1 is legacy; always use V2 unless V1 is specified or the chain requires it (Noble, Sui, and Aptos still require V1). Migration guide: https://developers.circle.com/cctp/migration-from-v1-to-v2.md.
> Use Bridge Kit for frontend bridging. Wraps CCTP with a simpler SDK for user-facing apps. Use CCTP directly for backend transfers.
> Gas Station vs Paymaster. Gas Station sponsors gas for Circle Wallet transactions. Paymaster lets users pay gas in USDC. Different use cases — read both overviews.
> Gateway Nanopayments for sub-cent payments. Gasless USDC micropayments down to $0.000001 via x402 and batched settlement. For pay-per-request APIs, AI agent payments, streaming.
> Look up USDC addresses per chain. Never hardcode — use https://developers.circle.com/stablecoins/usdc-contract-addresses.md.
> Prefer SDKs over raw API calls. Node.js and Python SDKs handle auth, retries, and errors.
> API key required. Bearer token in Authorization header. Testnet and mainnet use separate keys and may use different base URLs depending on the product.
> Set up webhooks when available. Most operations are async. Webhooks deliver transaction confirmations and state changes.
> When calling list endpoints, paginate using pageSize and pageAfter until no nextPageAfter cursor is returned—stopping at the first page silently misses records.
> Building an AI agent? Start with the Agent Stack—Circle CLI, agent wallets, and nanopayments built for autonomous use cases: https://developers.circle.com/agent-stack.md.

# Technical guide for Gateway on Solana

> Differences between Gateway on Solana and EVM

## Overview

The Solana Gateway protocol implementation is split into two programs:
`GatewayWallet` and `GatewayMinter`. To ensure alignment with EVM contracts'
logic and state, and to facilitate upgrades and maintenance, the code and state
of Solana programs reflect the EVM counterparts as closely as possible.

Key differences for Solana:

* Where canonical addresses are expected in the API, Solana addresses should be
  represented as base58.
* Where 32-byte addresses are expected in the API, Solana addresses should be
  represented as hex.
* All block height expiration fields in the API (such as `maxBlockHeight` and
  `expirationBlock`) refer to the last *slot* before the signed message is
  invalid.
* `BurnIntentSets` originating from Solana are not supported. Each transfer from
  Solana must be specified as a separate signed `BurnIntent`.
* Solana uses a reduced attestation format to accommodate transaction size
  limits.

## Message formats

Gateway on Solana uses the same message formats as on EVM for the
[`TransferSpec`](/gateway/references/technical-guide#transfer-specification) and
[`BurnIntent`](/gateway/references/technical-guide#burn-intent) messages. These
messages are described in the
[Gateway technical guide](/gateway/references/technical-guide).

Gateway on Solana uses a reduced attestation format to accommodate transaction
size limits.

For static Solana instruction and account definitions, use the onchain program
IDLs as the source of truth:

* [`GatewayWallet` IDL](https://explorer.solana.com/address/GATEwy4YxeiEbRJLwB6dXgg7q61e6zBPrMzYj5h1pRXQ/idl)
* [`GatewayMinter` IDL](https://explorer.solana.com/address/GATEm5SoBJiSw1v2Pz1iPBgUYkXzCUJ27XSXhDfSyzVZ/idl)

This page provides high-level Solana-specific guidance, including signing rules,
integration constraints, and reduced attestation concepts.

### `ReducedMintAttestation`

A mint attestation contains the details needed for the `GatewayMinter` to mint.
Mint attestations on Solana use a "reduced" encoding to account for Solana's
transaction size limits. On Solana, all attestations are
`ReducedMintAttestationSets`. This reduces ambiguity when decoding
`MintAttestations` and saves transaction size on common fields between elements
that have been hoisted to the set level.

All integer fields in the reduced attestation encoding use big-endian byte
order. In Solana payout flows, the `destinationRecipient` field must contain the
initialized USDC token account or Associated Token Account that will receive the
mint, not the recipient wallet address.

#### Reduced attestation structure

The following tables are provided as implementation guidance for Solana reduced
attestation parsing. For canonical static program interfaces, rely on the
onchain IDLs.

#### Attestation set encoding

| Field | Offset | Bytes | Description |
| :- | :- | :- | :- |
| `magic` | 0 | 4 | `0x10cbb1ec` |
| `version` | 4 | 4 | Protocol version |
| `destinationDomain` | 8 | 4 | Destination domain identifier |
| `destinationContract` | 12 | 32 | Minter contract address |
| `destinationCaller` | 44 | 32 | Allowed caller address |
| `maxBlockHeight` | 76 | 8 | Expiration slot |
| `numAttestations` | 84 | 4 | Number of attestation elements |
| `attestations` | 88 | var | Array of attestation elements |

#### Attestation element encoding

| Field | Offset | Bytes | Description |
| :- | :- | :- | :- |
| `destinationToken` | 0 | 32 | Token address on destination |
| `destinationRecipient` | 32 | 32 | Recipient address |
| `value` | 64 | 8 | Amount to mint |
| `transferSpecHash` | 72 | 32 | `keccak256` hash of the TransferSpec |
| `hookDataLength` | 104 | 4 | Length of hook data |
| `hookData` | 108 | var | Hook data bytes |

Unlike standard `MintAttestation` messages, the `ReducedMintAttestation` does
not include the full `TransferSpec`. The `TransferSpec` hash is encoded directly
into the message and can be used as a unique crosschain identifier. Retrieve the
original `TransferSpec` through the
[Get transfer spec](/api-reference/gateway/all/get-transfer-spec) endpoint.

## Signing

### `BurnIntent` signing

Once a `BurnIntent` has been constructed, prepend the signing domain header
(`0xff000000000000000000000000000000`) before signing using the ed25519 keypair
associated with the source depositor. Alternatively, sign with a delegated
address.

| Field | Offset | Bytes | Description |
| :- | :- | :- | :- |
| `signingDomain` | 0 | 16 | `0xff000000000000000000000000000000` |
| `burnIntent` | 16 | var | Encoded `BurnIntent` |

The signing domain header ensures:

1. The signature cannot authorize a transaction due to illegal first byte
   (`0xff`).
2. The program can be upgraded to support
   [Off-Chain Message Signing Format (OCMSF)](https://docs.anza.xyz/proposals/off-chain-message-signing)
   without introducing ambiguity between signing payload types.

### `MintAttestation` signing

`ReducedMintAttestation` messages are signed by the Gateway API service using
EVM-style ECDSA signatures. The `keccak256` hash of the message is signed by the
Circle attestation signer according to
[EIP-191](https://eips.ethereum.org/EIPS/eip-191), using the `personal_sign`
(`0x45`) format.

## Transaction size limits

Solana transactions can be at most 1232 bytes. To maximize composability of
`gatewayMint` instructions, the protocol minimizes the data size needed to
execute mints. The `ReducedMintAttestation` message reduces the size of the
original `MintAttestation` designed for EVM by removing fields that do not need
to be validated on the destination chain. The parameter mode for `gatewayMint`
further reduces redundancy by inferring data from the execution context or
account list.

To ensure that USDC supply can be maintained 1:1, the Gateway Transfer API
rejects user `BurnIntents` that are too large to be safely executed on Solana.
Verify your transaction sizes before broadcasting transactions using the
`gatewayMint` instruction.

### Executing large mint attestations

You can execute large `MintAttestations` that exceed the transaction size limit,
as long as strict atomicity is not required. Deploy a separate program that
writes `MintAttestation` data into a buffer account across multiple
transactions. Once the message has been written to the buffer account, this
program can execute a cross-program invocation (CPI) into the Gateway Minter
program, passing in the `MintAttestation` bytes from the buffer account as an
argument. CPI calls can be at most 10 \* 1024 bytes.
