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

# Routing accounts

> How accounts are passed per hop on the AMM Routing program: user ATAs for every intermediate token, then the per-pool account block for each leg of the route.

## Account layout: user ATAs all the way through

Every enabled swap variant routes intermediate tokens through **user-controlled ATAs**. The user owns the input ATA, every intermediate ATA, and the final output ATA. There is no shared / router-owned intermediate token account in the active surface.

Properties:

* User owns one ATA per intermediate token.
* User provides every ATA in the accounts list.
* Each intermediate ATA must already exist (initialize it with `CreateSyncNative` for wSOL, or via the SPL Associated Token Account program for any other mint, before routing).
* The router transfers out of one ATA and into the next pool's vault on each hop.
* Each intermediate ATA ends each route with the same balance it started with — the route consumes whatever the previous hop produced.

Example flow for route `USDC → SOL → STEP`:

```
Accounts list:
  [
    USDC_input_ata (user, signer),
    SOL_intermediate_ata (user),
    STEP_output_ata (user),
    token_program,

    amm_program_1, *amm1_accounts,    // hop 1: USDC → SOL
    amm_program_2, *amm2_accounts,    // hop 2: SOL → STEP
  ]

Hop 1: USDC_input_ata → AMM1 → SOL_intermediate_ata
Hop 2: SOL_intermediate_ata → AMM2 → STEP_output_ata
```

## Per-hop account layout

Each hop's accounts are passed consecutively. The router identifies the child program by reading the first account in each hop's block (the program ID), then dispatches to the correct handler.

For each hop, the router expects accounts grouped as:

```
[
  program_id,         // Identifies which pool program (AMM v4, CPMM, CLMM, Stable)
  *child_accounts,    // All accounts required by that pool's swap instruction
]
```

The child accounts vary by pool type:

### AMM v4 hop

Approximately 18 accounts: pool, authority, vaults, mints, OpenBook market accounts (kept on the account list for backwards compatibility even though AMM v4's OpenBook integration is no longer active), token programs. See [`products/amm-v4/accounts`](/products/amm-v4/accounts) for the full list.

### CPMM hop

Approximately 11–13 accounts: pool state, authority, vaults (2), mints (2), token programs, system program, associated token program. See [`products/cpmm/accounts`](/products/cpmm/accounts).

### CLMM hop

Approximately 15+ accounts: pool, tick arrays, vaults, mints, observation state, signer, token programs. See [`products/clmm/accounts`](/products/clmm/accounts).

### Stable hop

Similar to AMM v4. See [`products/stable/accounts`](/products/stable/accounts).

## Token flow and ATA ownership

* The caller signs with `user_input_ata`.
* The caller **must own** all input, intermediate, and output ATAs. The router will reject the transaction if any intermediate ATA's owner is not the signer.
* The caller's `user_input_ata` balance must be sufficient for the first hop's input (`amount_in` for tag 0 / 8, or `maximum_amount_in` for tag 1 / 9).
* Each intermediate ATA must already exist on-chain. If it does not, create it ahead of time — typically via the [SPL Associated Token Account program](https://spl.solana.com/associated-token-account), or with `CreateSyncNative` (tag 5) for a wSOL ATA.

## The CreateSyncNative instruction

If you need to route through wrapped SOL and do not want to manually create and sync a wSOL ATA, use [`CreateSyncNative`](/products/routing/instructions#createsyncnative-tag-5) (tag 5):

```
CreateSyncNative(amount)
```

This creates a wSOL ATA under the caller's wallet, transfers `amount` of SOL into it via the System Program, and syncs it in one instruction. Useful for initializing a fresh wSOL ATA before routing.

## The CloseTokenAccount instruction

After a route completes you may want to close any intermediate ATA — most commonly a wSOL ATA — to reclaim rent. Use [`CloseTokenAccount`](/products/routing/instructions#closetokenaccount-tag-6) (tag 6):

```
CloseTokenAccount
```

The token account must have a zero token balance before close; the router will not auto-empty it for you.

## Where to go next

* [`products/routing/instructions`](/products/routing/instructions) — argument shapes and account-list order per instruction.
* [`products/routing/code-demos`](/products/routing/code-demos) — building a route in TypeScript.
* [`reference/program-addresses`](/reference/program-addresses) — child program IDs.
