# Intents and orders

> What an intent is, how an API order becomes one, and how partial fills form a chain.

## What an intent is

An intent is a declaration of an acceptable outcome, authorized by its owner: what must be true when it settles, not the steps to get there.

> "Get me from New York to Paris tomorrow, in under eight hours, for under $800." The traveller fixes price, timing and destination. The travel agent chooses the airlines and the connections.

On Khalani an intent escrows its source value up front and states the outcome it accepts. The hub releases the escrow only for a fill that meets that outcome. A fill that doesn't meet it cannot execute, so the user never carries that risk.

An intent has two sides:

- **Give:** the escrowed source, an amount of one mToken.
- **Get:** the outcome it accepts. The hub accepts two shapes today: an exact amount of one destination mToken, or a **rate** that any fraction of the source can be filled at. API orders always use the rate. The intent format also defines minimums, ranges and multiple acceptable assets, which the hub does not accept yet.

## How an order becomes an intent

An order built with `POST /v2/build` becomes one intent on the hub, the **root intent**, when its deposit arrives:

- **Give:** the deposit, in source mTokens, less the fees withheld at publish.
- **Get:** the destination mToken at the quoted rate (`intentOutcomeRate`), fillable in any fraction.
- **Valid until:** the order's deadline.

The order's terms (pair, amount, rate, flat fee, recipients, deadline) were signed at build and must match the deposit the user sent. No API call or transaction can change them after the deposit. `traces.rootIntentId` in the order response is this intent's id, and a cancel signs against it.

## Partial fills form a chain

A rate-based intent can fill in pieces. When a solver fills part of it, the hub splits the intent in the same transaction: the filled slice's output is credited to the order on the hub, the parent closes, and the remainder becomes a **child intent**. Nothing is paid out to the user until the order settles.

The child is not a new order. The hub requires it to carry the parent's exact terms (same author, rate and deadline), so only the amount shrinks. A sequence of partial fills therefore forms a chain in which every link holds the rate of the original order:

```mermaid
flowchart LR
    root["root intent<br/>1,000"] -- "remainder 400" --> c1["child 1<br/>400"]
    c1 -- "remainder 150" --> c2["child 2<br/>150"]
    c2 --> tip["tip<br/>open, filled, expired<br/>or cancelled"]
    root -. "filled 600" .-> p1["credited at the rate"]
    c1 -. "filled 250" .-> p2["credited at the rate"]
```

The API reports the whole chain as one order. `traces.chainObservations` records each link as it is observed.

## How an intent ends

The last child in the chain is its **tip**. It either fills completely, reaches the deadline, or is cancelled, and one settlement transaction then closes the order:

- the filled amount, at the order's rate, is paid to `payoutAddr` on the destination chain,
- the unfilled share of the deposit, after the flat fee, is refunded to `refundAddr` on the source chain,
- the fees are taken: the flat fee in full, the percentage fees on the filled part only.

Each order settles once. Cancels and fills are applied in sequence, so a cancel that races a fill settles what was filled and refunds the rest.
