> ## 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.

# 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.
