> ## 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: Decoding settle programs

> Decoding settle programs: the declaration and description of each of the 11 exports of @eco-incorp/sauce/verify.

`@eco-incorp/sauce/verify` checks an EVM settle payload: its program bytes against accepted program pins (by default, the settle program this package pins), and its argument tail `(tokens, minOut, recipient)` against the canonical encoding. It imports viem only, so it runs in a browser or an edge runtime without loading the compiler.

```typescript theme={null}
import { validateSettleProgram, encodeSettleProgram } from "@eco-incorp/sauce/verify";
```

Generated from the type declarations of `@eco-incorp/sauce`.

### `decodeSettleProgram`

*Function* · `@eco-incorp/sauce/verify`

Decode a settle payload back into `(tokens, minOut, recipient)`. STRICT: rejects a non-canonical
tokens pointer, a tail longer or shorter than the token count implies, an address word with
dirty upper bytes, and a zero recipient. Throws `SettleDecodeError` (carrying a
stable `.code`) on any of the failures in `SettleFailureCode`.

Structural decoding splits at `programBytes` and requires a canonical argument tail.
It does not authenticate the prefix. Use `validateSettleProgram` to check program identity.

```typescript theme={null}
export declare function decodeSettleProgram(payload: Hex, programBytes?: number): DecodedSettleProgram;
```

### `validateSettleProgram`

*Function* · `@eco-incorp/sauce/verify`

Authenticate an accepted program hash and length, then decode its canonical argument tail.
The default accepts only the current `SETTLE_WIRE` pin.

`accepted` replaces the default set; an empty list rejects every program. To retain historical
payloads across compiler upgrades, include their `{ hash, bytes }` records explicitly.
A bare hash uses the current program length and is suitable only for a same-length program.
The first matching pin is used.

Throws `SettleDecodeError` with code `PROGRAM_HASH` for an unrecognized program, or a structural
decoding error when a recognized program carries malformed arguments.

```typescript theme={null}
export declare function validateSettleProgram(payload: Hex, accepted?: readonly (Hex | ProgramPin)[]): DecodedSettleProgram;
```

### `encodeSettleProgram`

*Function* · `@eco-incorp/sauce/verify`

The cheaper, EQUIVALENT alternative to scan-and-check: when the caller
already knows the intended `(tokens, minOut, recipient)` (the normal case - they asked for the
swap), encode them directly and `memcmp`/hash-compare the whole payload rather than decoding.
This produces the UNIQUE canonical encoding, so `encodeSettleProgram(...)` equals
`payload` exactly when `validateSettleProgram(payload)` succeeds with those values - in one
comparison, with no parser exposed to a hostile input at all. This is the recommended
non-TypeScript (Solidity/Go/Python) implementation, where a payload is bytes and the comparison is
a plain `memcmp`.

THE EQUIVALENCE IS OVER BYTES, NOT OVER HEX SPELLINGS. `validateSettleProgram` accepts any spelling
of the same bytes - uppercase, a `0X` prefix, no prefix at all - while this returns canonical
lowercase `0x`. So `validateSettleProgram(p.toUpperCase())` succeeds where
`encodeSettleProgram(...) === p.toUpperCase()` is `false`. A string `===` is only equivalent once
both sides are in canonical spelling; normalize first, or compare decoded bytes.

`programHex` is supplied by the caller - pass the program you compiled yourself. There is
deliberately no default: the bytes you compare against should be ones you derived, not ones
shipped alongside the claim they support. `SETTLE_WIRE.PROGRAM_HASH` is what to check them
against once you have them.

```typescript theme={null}
export declare function encodeSettleProgram(tokens: readonly (bigint | `0x${string}`)[], minOut: bigint, recipient: bigint | `0x${string}`, programHex: Hex): Hex;
```

### `parseSettleProgram`

*Function* · `@eco-incorp/sauce/verify`

Best-effort single left-to-right pass - never throws. This is the shared engine both
`decodeSettleProgram` (throws on `parse.fatal`) and `bestEffortDecode` (keeps whatever DID
parse even when a later stage failed) run on top of.

```typescript theme={null}
export declare function parseSettleProgram(payload: Hex, programBytes?: number): SettleParse;
```

### `bestEffortDecode`

*Function* · `@eco-incorp/sauce/verify`

Decode whenever the shape is well-formed enough to name a full `(tokens, minOut, recipient)` - even when a check that does not block reading (a trailing-slack tail, a dirty address word, a
zero recipient) would make `decodeSettleProgram` throw - so a rejected payload's decoded values are
still visible to a caller debugging the rejection.

DECLINES wherever the report would not match execution - the whole point being that on a hostile
payload, reporting nothing beats reporting a wrong answer confidently. Two cases:

* a non-canonical tokens pointer: the engine follows it, this reads at the canonical offset, so the
  two name different TOKENS.
* a dirty RECIPIENT word: `recipient` is masked here, but the engine does not mask that word,
  so execution addresses a different 256-bit key than the masked answer would suggest.

A dirty TOKEN word is NOT declined: the engine masks a call target to 160 bits, so there the masked
answer is exactly what executes, and reporting it is what shows the payload's true meaning.

```typescript theme={null}
export declare function bestEffortDecode(parse: SettleParse): DecodedSettleProgram | null;
```

### `SettleDecodeError`

*Class* · `@eco-incorp/sauce/verify`

```typescript theme={null}
export declare class SettleDecodeError extends Error {
    readonly code: SettleFailureCode;
    constructor(code: SettleFailureCode, message: string);
}
```

### `DecodedSettleProgram`

*Interface* · `@eco-incorp/sauce/verify`

```typescript theme={null}
export interface DecodedSettleProgram {
    tokens: Address20[];
    minOut: bigint;
    recipient: Address20;
    floorToken: Address20;
    program: Hex;
    programHash: Hex;
    args: Hex;
    argsSize: number;
    payloadSize: number;
}
```

### `ProgramPin`

*Interface* · `@eco-incorp/sauce/verify`

An accepted program: its `keccak256` AND the byte length the payload splits at. Both are needed - the split happens before any hash is computed, so a historical pin whose program was a different
length cannot be matched by hash alone.

```typescript theme={null}
export interface ProgramPin {
    hash: Hex;
    bytes: number;
}
```

### `SettleFailureCode`

*Type* · `@eco-incorp/sauce/verify`

Stable failure codes - safe to `switch` on. Every one is a REAL rejection this decoder makes.

The wire is fixed-width, so the codes name only defects a fixed-width payload can have: `EMPTY`
and `ZERO_RECIPIENT` for the payload and its recipient, `PROGRAM_TRUNCATED`, `ARGS_TRUNCATED`,
`ARGS_OVERLONG`, `TOKENS_OFFSET`, `TOKENS_EMPTY` and `DIRTY_ADDRESS_WORD` for its layout, and
`PROGRAM_HASH` for a program that is not the pinned one. Canonicality and `PROGRAM_HASH`
together make each accepted payload the unique encoding of its meaning.

```typescript theme={null}
export type SettleFailureCode = "EMPTY" | "PROGRAM_TRUNCATED" | "ARGS_TRUNCATED" | "ARGS_OVERLONG" | "TOKENS_OFFSET" | "TOKENS_EMPTY" | "DIRTY_ADDRESS_WORD" | "ZERO_RECIPIENT" | "PROGRAM_HASH";
```

### `SettleParse`

*Interface* · `@eco-incorp/sauce/verify`

Internal parse result - used by both the throwing `decodeSettleProgram` and the non-throwing
`bestEffortDecode`, which keeps partial state past a failure.

```typescript theme={null}
export interface SettleParse {
    bytes: Uint8Array;
    program: Uint8Array | null;
    programHash: Hex | null;
    args: Uint8Array | null;
    tokensOffset: bigint | null;
    minOut: bigint | null;
    recipient: bigint | null;
    recipientWord: bigint | null;
    recipientNonZero: boolean;
    tokenCount: bigint | null;
    tokenWords: bigint[];
    fatal: {
        code: SettleFailureCode;
        message: string;
    } | null;
}
```

### `Address20`

*Type* · `@eco-incorp/sauce/verify`

A 20-byte address rendered as lowercase 0x-hex - deliberately NOT `viem`'s `Address` branded
type: callers that want an EIP-55 checksum should `getAddress()` it themselves.

```typescript theme={null}
export type Address20 = `0x${string}`;
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.