Skip to main content
Solana is a supported Intents chain (mainnet solana:1151111081099710). It is not an EVM-compatible runtime: programs replace contracts, accounts replace storage, and rent, PDAs, and transaction size limits shape how orders work. The high-level mental model is unchanged — input settlement, output settlement, oracle validation — but several mechanics differ. This page is a delta reference: for each concern, what EVM does and what Solana does instead. It starts with a short platform primer for readers coming from EVM.
For general (non-Intents) Solana support across LI.FI products, see the Solana ecosystem page.

At a glance

The table summarizes every delta on this page; the sections below explain each one.

Solana in sixty seconds

The Solana pages lean on a few platform fundamentals. If you come from an EVM background, this is enough to follow along; each item links to the official docs for depth.
  • Program Derived Address (PDA). An account address derived deterministically from a program id and a list of seeds. PDAs have no private key — only the deriving program can sign for them. The intent system uses PDAs everywhere: escrows, attestations, and configuration all live at addresses anyone can recompute, which is why “the account exists at the expected PDA” can serve as a proof. Solana docs: PDAs
  • Cross-program invocation (CPI). One program calling an instruction on another within the same transaction — Solana’s equivalent of a contract calling a contract. The output settler creates attestation accounts by CPI into the intents_protocol program. Solana docs: CPI
  • Associated token account (ATA) and rent. SPL token balances live in separate token accounts, not in the wallet address itself; the ATA is the canonical token account for an (owner, mint) pair. Every account must hold a small SOL deposit (“rent”) to exist — whoever creates an account pays the rent and gets it back when the account closes. This is why orders track a sponsor (who paid rent at open and is repaid the escrow token account and order_context rent when the order closes — the consumed_order rent is a permanent per-order cost), why solvers may pay rent when a recipient’s ATA does not exist yet, and why fill records and attestations record who paid for them so that rent can be returned later. SPL docs: ATAs
  • Anchor. The framework the intent programs are written in. It declares each instruction’s accounts, generates an IDL (comparable to an EVM ABI) for clients, and prefixes events and accounts with discriminators. The TypeScript examples use Anchor’s client library, @coral-xyz/anchor. Anchor docs
  • remaining_accounts. Anchor instructions declare a fixed account list, but callers can append extra accounts at the end. The intent system uses them for lists whose length depends on the order — such as one attestation account plus one rent-refund account per output at finalise.
  • Borsh. The binary serialization format Anchor uses for instruction data, accounts, and events. Order ids derive from it: order_id = keccak256(borsh_serialize(StandardOrder)). Borsh
  • Base58 and bytes32. Solana addresses are 32-byte ed25519 public keys displayed as base58 strings (e.g. EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v). The cross-chain order format stores all addresses as raw 32-byte values: a Solana address is the base58-decoded 32 bytes, while a 20-byte EVM address is left-padded with zeros.
  • Verifiable action approval (VAA). Wormhole’s signed message format — an attestation by Wormhole’s guardian network that an event happened on a source chain. The Wormhole oracle posts fill proofs as VAAs. Wormhole docs: VAAs

Chain IDs

In API requests, Solana chains use CAIP-2-derived ids in the solana namespace: On-chain, the protocol uses a u128 chain id stored in the intents_protocol ChainId PDA. That value — not the EVM-style native chainId — is what appears in StandardOrder.origin_chain_id and MandateOutput.chain_id, and what programs validate against. Solana has no single “chain id” — three namespaces coexist, and each surface expects exactly one of them: Using a value from the wrong namespace fails indirectly. Quoting a Solana leg under eip155: is rejected with an error about the asset encoding rather than the namespace. A Polymer proof requested with the canonical id instead of 2 is refused by the Prove API — see Oracle systems for the Polymer flow.

Quoting

Solana is served by the standard quote endpoint, POST /api/v1/integrator/quote/request — the same one EVM and Tron use. Pass Solana addresses as base58 with the solana: CAIP-2 chain id and get base58 back. Request and response examples are in Request a Quote. Solana is not served by the legacy V0 endpoint. For a Solana-origin order, the winning quote returns a ready-to-open transaction rather than an order to submit. The order.openIntentTx fields differ from EVM:
  • to is the input settler program id, in base58.
  • data is a base58-encoded, serialized v0 VersionedTransaction, not calldata. Its recentBlockhash is a dummy all-zeros value (11111111111111111111111111111111) and must be replaced with a fresh blockhash before signing — Solana blockhashes expire after roughly a minute.
  • computeUnitsRequired estimates the compute units the transaction needs (a decimal string). The serialized template does not contain a Compute Budget instruction; rebuild the message with ComputeBudgetProgram.setComputeUnitLimit before signing, as shown in Opening on Solana.
  • checks.allowances is always []: the SPL transfer happens inside the open instruction, so there is no approval pre-step.
  • metadata.exclusiveFor, when set, is the input-chain solver identity with the exclusive right to fill during the exclusivity window. For a Solana-origin order it must be the base58 Solana public key that will sign finalise, even when the output is on EVM.

Token support

xStocks use Token-2022 and can use the standard quote flow when a specific mint’s current configuration is compatible. Compatibility is evaluated per mint against its on-chain configuration. A mint is rejected when any of the following holds:
  • Active transfer hook — the transfer-hook extension has a hook program set. The extension may be present with no program configured, in which case the mint remains compatible.
  • Non-zero transfer fee — the transfer-fee extension is configured with a fee above zero in either the current or the scheduled epoch. A zero-fee configuration (as on PYUSD) is compatible.
  • Non-transferable — the mint carries the non-transferable extension, so no transfer can ever succeed.
  • Unresolvable mint — the mint account does not exist or is not owned by a known token program.
Other extensions, including ones the service does not yet recognize, do not by themselves cause a mint to be rejected. This eligibility check is not a guarantee that every transfer will succeed: issuer-controlled restrictions such as pausing or freezing can still make simulation or execution fail. Transfer-hook programs and fee rates can also change, so a mint’s compatibility can change over time. The same policy is enforced twice: the quote endpoint returns an empty quote list for an incompatible mint (or when the mint cannot be read), and orders opened on-chain that reference an incompatible mint are not distributed to solvers.

Settlement: escrow only

Solana supports only the escrow input settler (input_settler_escrow). There is no Compact or resource-lock flow, so the Compact Orders guide does not apply to Solana.

One input per order

A Solana order carries exactly one input — a single { token, amount } pair (MandateInput) — where an EVM order can carry an array of inputs. If you need to spend several tokens, you need several orders.

Amounts are u64

Solana narrows the wire-format 32-byte amount and Dutch-auction slope fields to u64, the SPL token limit; EVM treats them as full-width uint256. When you build cross-chain Dutch orders destined for Solana, keep the slope and the maximum resolved amount within u64 range, or the output cannot be filled. See Auctions for the pricing formula.

Order size

On EVM, order size is practically unbounded. On Solana, the whole StandardOrder travels in the instruction data of open and finalise, and finalise adds an attestation account and a rent-refund account per output — all inside Solana’s 1,232-byte transaction packet. The escrow enforces the bound at open: it projects the finalise transaction as 760 + 302·N + Σ(|callback_data| + |context|) bytes for N outputs and rejects the order (FinaliseTxTooLarge) above 1,142 bytes — the packet cap minus headroom reserved for compute-budget instructions, with 32 bytes credited back when the sponsor is the user. An order that opens can therefore always be finalised with a bare finalise transaction; re-check the bound only if you append instructions of your own. The practical consequence: an order opened on Solana has exactly one output. One output projects to 1,062 bytes (1,030 when the sponsor is the user), leaving 80 bytes (112) for callback_data and context — enough for every order type when there is no callback data (the largest context, exclusive Dutch auction, is 73 bytes). Two outputs project to at least 1,332 bytes and are always rejected. Orders that originate on another chain are not limited this way and can deliver several outputs on Solana.

Proofs are accounts

EVM stores fill proofs in contract storage behind validation interfaces. Solana stores them as deterministic PDA accounts: a LocalAttestation for a fill on Solana, an Attestation for a remote proof registered by an oracle. The full model — seeds, payload encodings, and the end-to-end flow — is in Attestations.

Same-chain swaps

Both platforms support same-chain intents, implemented differently. On Solana, these orders put the output-settler state PDA in all three identity slots (settler, oracle, inputOracle) — see the identity matrix. On the standard route, fill creates a LocalAttestation and finalization validates that account directly — no oracle program involved. The escrow is not the attestation’s consumer under this encoding, so the attestation’s rent is not returned. On the input-first route below, no attestation is created at all. On EVM, same-chain is modeled as an oracle configuration (the output settler doubles as the oracle). Both platforms can release the input before output delivery. Their execution models differ: See Input-first Solana settlement for the solver workflow and constraints.

One fill per instruction

There is no Solana equivalent of fillOrderOutputs that atomically fills several outputs at once. You fill each output with its own instruction, one after another. This matters for orders from another chain with several Solana outputs; an order opened on Solana has a single output.

Next steps

Solana programs

The Anchor programs, structs, and instructions behind Solana intents