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

# intent-router

> Session-based state machine that attests a multi-step fixed-rate lock.

<style>
  {`
    .katex-display {
      overflow-x: auto;
      overflow-y: hidden;
      scrollbar-width: none;
      -ms-overflow-style: none;
    }
    .katex-display::-webkit-scrollbar {
      display: none;
      height: 0;
      width: 0;
    }
    `}
</style>

`intent-router` is a thin coordinator. It does not execute trades, it records
each step the user performs across delta-vault, split-engine, and yield-amm,
and verifies the end-to-end achieved rate meets the user's target.

## Accounts

### IntentSession

`["session", owner, session_id_le]`.

| Field            | Type           | Notes                                                    |
| ---------------- | -------------- | -------------------------------------------------------- |
| `owner`          | `Pubkey`       | User                                                     |
| `state`          | `SessionState` | `Created`, `Step1Complete`, `Step2Complete`, `Completed` |
| `session_id`     | `u64`          | Client-supplied nonce                                    |
| `target_rate`    | `u64`          | Minimum APY (9-decimal fixed point)                      |
| `duration`       | `i64`          | Lock duration in seconds                                 |
| `amount`         | `u64`          | USDC deposited                                           |
| `vault_shares`   | `u64`          | After Step 1                                             |
| `pt_received`    | `u64`          | After Step 2                                             |
| `yt_received`    | `u64`          | After Step 2                                             |
| `market`, `pool` | `Pubkey`       | The split-engine market + yield-AMM pool used            |
| `bump`           | `u8`           |                                                          |

## Instructions

| Instruction      | Purpose                                                                                             |
| ---------------- | --------------------------------------------------------------------------------------------------- |
| `create_session` | Open session (`Created`); stores `target_rate`, `duration`, `amount`, `market`, `pool`              |
| `record_step1`   | Verify `vault_shares` delivered; advance to `Step1Complete`                                         |
| `record_step2`   | Verify `pt_received`, `yt_received`; advance to `Step2Complete`                                     |
| `record_step3`   | Verify swap; compute `achieved_rate`; require `achieved_rate ≥ target_rate`; advance to `Completed` |
| `close_session`  | Close account, refund rent (any state)                                                              |

## Rate formula (record\_step3)

Given `pt_sold` and `underlying_received` from the AMM swap:

$$
\text{discount} = \text{pt\_sold} - \text{underlying\_received}
$$

$$
\text{achieved\_rate} = \frac{\text{discount} \times \text{ONE} \times \text{SECONDS\_PER\_YEAR}}{\text{underlying\_received} \times \text{duration}}
$$

If `achieved_rate < target_rate`, the instruction errors with
`TargetRateNotAchievable` and the session stays at `Step2Complete`. The user's
PT and YT tokens are untouched, they can unwind manually.

## Events

Only `IntentFulfilled` is emitted as an Anchor `#[event]` (at `record_step3`,
carrying `owner`, `session_id`, `amount`, `target_rate`, `achieved_rate`,
`pt_received`, `yt_received`). Session creation and the interim steps log
progress via `msg!` and by advancing the session account's `state` field.

## Errors

`InvalidSessionState`, `TargetRateNotAchievable`, `TargetRateNotAchieved`,
`SessionCompleted`, `NotSessionOwner`, `MathOverflow`, `ZeroAmount`,
`NoSharesReceived`, `NoTokensReceived`, `SlippageExceeded`,
`PtBalanceMismatch`, `UnderlyingBalanceInsufficient`, `NoSwapPerformed`,
`NegativeDiscount`, `InvalidDuration`.

## Read next

<CardGroup cols={2}>
  <Card title="Fixed-rate intents" icon="route" href="/concepts/fixed-rate-intents">
    Why the session exists.
  </Card>

  <Card title="Lock a fixed rate" icon="lock" href="/guides/lock-fixed-rate">
    Full code walkthrough.
  </Card>
</CardGroup>
