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

# verify: Intent decoding

> Intent decoding: 7 exports of the verify module of @eco-incorp/sauce, including decodeSettleCall, extractEvmSettleFromCalls, extractEvmSettleFromIntent, DecodedSettleCall, ExtractedEvmSettle, IntentCallLike.

`@eco-incorp/sauce/verify` validates an EVM settlement payload against the pinned settle program (`SETTLE_WIRE`: compiler 2.3.0, 356 bytes) and decodes its runtime argument tail. It depends on viem only, so it runs in browsers and edge runtimes without loading the compiler.

This page covers `sdk/dist/verify/intent.d.ts`.

<Note>
  Generated from the type declarations shipped in `@eco-incorp/sauce` 0.99.4. Each entry shows the package authors' JSDoc and declaration for this SDK version. For runtime compatibility and deployed addresses, see [architecture and deployments](/programmable-transactions/sauce/architecture-and-deployments).
</Note>

### `decodeSettleCall`

*Function* · `sdk/dist/verify/intent.d.ts`

Decodes one `Pot.cook(address,bytes)` / `SauceRouter.cook(bytes[])` call and returns the settle payload it
carries - or `null` if the calldata is not a `cook` call, or ingredient 0 is not the settle payload.
Never throws for a non-cook / non-settle input: a mismatched selector, malformed ABI, or a non-settle
ingredient 0 all return `null`.

The index-0 rule is a `V12Pot` property, and on a v1 `SauceRouter` it cuts BOTH ways, because a
SauceRouter executes EVERY ingredient. A settle at index ≥1 reads as `null` here (a missed settle - harmless); but `cook([settlePayload, drainPayload])` on a SauceRouter validates index 0, returns the
settle, and the drain runs too - a settle reported for a call that does more than settle. The
returned `ingredientCount` is how a caller detects that: require it to be 1 on a SauceRouter. So a
non-null result is a statement about a v12 cook ONLY. On a SauceRouter it is not sufficient, for the
same reason `extractEvmSettleFromCalls` is not sufficient across `route.calls[]`. The detection IS `validateSettleProgram` (the pinned
program hash, plus a canonical tail), so an accepted ingredient is the audited settle program AND the
unique byte encoding of the `(tokens, minOut, recipient)` reported.

```typescript theme={null}
export declare function decodeSettleCall(callData: Hex, accepted?: readonly (Hex | ProgramPin)[]): DecodedSettleCall | null;
```

### `extractEvmSettleFromCalls`

*Function* · `sdk/dist/verify/intent.d.ts`

Scans an intent's `route.calls[]` and returns the settle params from the first `cook` call carrying
the settle payload - the EVM settle in a batch is a `Pot.cook(settleBytecodes)` alongside a
`Pot.cook(swapBytecodes)`, so this finds it by CONTENT (which cook validates as settle), not by
position. `null` if no call carries one.

LOCATES THE SETTLE; DOES NOT CLEAR THE INTENT. Unlike a cook's sibling ingredients - where only
ingredient 0 runs, so reading further would describe dead bytes - EVERY entry in `route.calls[]`
executes. This returns the first entry that validates and leaves the others UNEXAMINED, so a
non-null result answers "this intent contains the audited settle, with these parameters" and NOT
"this intent does only that": in `[cook([drain]), cook([settle])]` the drain is real, executes
first, and is not reported. A caller deciding whether an intent is safe must check `callIndex`
against its own expectation and account for the remaining calls itself.

AND IT MUST VALIDATE `target` AND `engine`. Matching is on a cook selector and the program bytes
ONLY - nothing here looks at the callee or the interpreter.

`target`: the one-program rule that makes a non-null result meaningful is a property of
`V12Pot.cook`, so it says nothing about an arbitrary contract that merely exposes that selector.
For `[{ target: attackerContract, data: cook(engine, canonicalSettlePayload) }]` this returns the
correct `(tokens, minOut, recipient)` while the attacker's `cook` ignores the payload entirely.
Compare it against a V12Pot address you trust; unvalidated, the parameters describe bytes that
were handed to an unknown contract.

`engine`: validating the program proves which BYTES run, not what runs them. The audited settle
program on an attacker-chosen interpreter is an attacker-chosen computation, and the interpreter
is a plain `cook` argument the producer picks. Compare it against your own allow-list,
CASE-INSENSITIVELY - it is reported lower-cased here, and a checksummed constant will not match
with `===`. It is `undefined` only for a v1 `SauceRouter.cook(bytes[])`, which names no engine.

Both are carried on the result for exactly these checks. Neither is validated here, because only
the caller knows which Pots and which interpreters it trusts.

```typescript theme={null}
export declare function extractEvmSettleFromCalls(calls: readonly IntentCallLike[], accepted?: readonly (Hex | ProgramPin)[]): ExtractedEvmSettle | null;
```

### `extractEvmSettleFromIntent`

*Function* · `sdk/dist/verify/intent.d.ts`

Extracts the EVM settle params `(tokens, minOut, recipient)` from an intent object - the thin
intent-level wrapper over `extractEvmSettleFromCalls`. Duck-typed on `{ route: { calls } }`, so it takes
an eco-solver `Intent` (runtime or persisted) as-is. `null` if the intent carries no settle cook.

```typescript theme={null}
export declare function extractEvmSettleFromIntent(intent: IntentLike, accepted?: readonly (Hex | ProgramPin)[]): ExtractedEvmSettle | null;
```

### `DecodedSettleCall`

*Interface* · `sdk/dist/verify/intent.d.ts`

```typescript theme={null}
export interface DecodedSettleCall extends DecodedSettleProgram {
    ingredientIndex: number;
    ingredientCount: number;
    engine?: `0x${string}`;
}
```

### `ExtractedEvmSettle`

*Interface* · `sdk/dist/verify/intent.d.ts`

```typescript theme={null}
export interface ExtractedEvmSettle extends DecodedSettleCall {
    callIndex: number;
    target?: `0x${string}`;
}
```

### `IntentCallLike`

*Interface* · `sdk/dist/verify/intent.d.ts`

An intent call, duck-typed: only `data` (the cook calldata) is required; `target` (the Pot address)
is carried through when present. Matches eco-solver's `Call` (`{ data, target, value }`).

```typescript theme={null}
export interface IntentCallLike {
    data: Hex;
    target?: `0x${string}`;
}
```

### `IntentLike`

*Interface* · `sdk/dist/verify/intent.d.ts`

An intent, duck-typed to just the calls this reads - so it accepts eco-solver's `Intent` (and its
persisted schema) without importing either.

```typescript theme={null}
export interface IntentLike {
    route: {
        calls: readonly IntentCallLike[];
    };
}
```
