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
maxBlockHeightandexpirationBlock) refer to the last slot before the signed message is invalid. BurnIntentSetsoriginating from Solana are not supported. Each transfer from Solana must be specified as a separate signedBurnIntent.- 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 theTransferSpec and
BurnIntent messages. These
messages are described in the
Gateway Technical Guide.
Gateway on Solana uses a reduced attestation format to accommodate transaction
size limits.
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.
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 |
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 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 signature cannot authorize a transaction due to illegal first byte
(
0xff). - The program can be upgraded to support Off-Chain Message Signing Format (OCMSF) 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, using the personal_sign
(0x45) format.
Transaction size limits
Solana transactions can be at most 1232 bytes. To maximize composability ofgatewayMint 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 largeMintAttestations 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.