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

# SDK Reference

> Public surface of @lifi/composer-sdk — the SDK factory, the FlowBuilder, handles, and supporting namespaces.

This page enumerates the public API of [`@lifi/composer-sdk`](https://unpkg.com/browse/@lifi/composer-sdk/src/sdk.ts). For the authoritative TypeScript types, browse the package source at [unpkg.com/browse/@lifi/composer-sdk](https://unpkg.com/browse/@lifi/composer-sdk/).

<Note>
  **There is no `sdk.compile()`.** Compile lives on the builder: `builder.compile(run)`. `sdk.request(flow, run)` is the escape hatch for custom transports.
</Note>

## `createComposeSdk(options)`

Declared in [`sdk.ts`](https://unpkg.com/browse/@lifi/composer-sdk/src/sdk.ts).

```ts theme={"system"}
const sdk = createComposeSdk({
  baseUrl: 'https://composer.li.quest',
  apiKey: process.env.LIFI_API_KEY,
  fetch: globalThis.fetch,
});
```

### `ComposeSdkOptions`

| Field     | Type                       | Notes                                                                                                                                         |
| --------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `baseUrl` | `string`                   | Base URL of the Compose API.                                                                                                                  |
| `apiKey`  | `string`                   | Required during the technical preview. Sent as the `x-lifi-api-key` header on every request. Get one at [portal.li.fi](https://portal.li.fi). |
| `fetch`   | `typeof globalThis.fetch?` | Defaults to the global `fetch`.                                                                                                               |

### `ComposeSdk`

Members:

| Member    | Signature                                                                   | Notes                                                                                             |
| --------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| `client`  | `ComposeClient`                                                             | Low-level HTTP client (`compile`, `getManifest`, `getZapPacks`). See [`sdk.client`](#sdk-client). |
| `flow`    | `<T>(chainId, options: FlowOptions<T>) => FlowBuilder<T>`                   | Creates a new flow builder.                                                                       |
| `request` | `<T>(flow: TypedFlow<T>, run: ComposeRunInput<T>) => ComposeCompileRequest` | Builds a compile request without sending it.                                                      |

## `sdk.flow(chainId, options)` → `FlowBuilder`

```ts theme={"system"}
const builder = sdk.flow(1, {
  name: 'my-flow',                                 // optional; defaults to a UUID
  inputs: {
    amountIn: resources.erc20(WETH, 1),
    deadline: 'uint256',
  },
});
```

### `FlowOptions<T>`

| Field    | Type                    | Notes                                                 |
| -------- | ----------------------- | ----------------------------------------------------- |
| `name`   | `string?`               | Human-readable id. Defaults to `crypto.randomUUID()`. |
| `inputs` | `T extends InputSchema` | Record of input name → `Resource` or `SolType`.       |

The generic `T` carries through to typed handles at `builder.inputs.<name>`.

## `FlowBuilder<T>`

A `FlowBuilder` is a `FlowBuilderCore<T>` (declared in [`FlowBuilderCore.ts`](https://unpkg.com/browse/@lifi/composer-sdk/src/authoring/FlowBuilderCore.ts)) augmented with **a typed method per op** plus a `compile` method.

### Inherited `FlowBuilderCore` members

| Member      | Signature                                     | Notes                                                                                                |
| ----------- | --------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `context`   | `ContextAccessor`                             | `{ sender, executionAddress }` — typed refs to runtime context values.                               |
| `inputs`    | `InputHandles<T>`                             | Typed handle per declared input. Resource inputs → `ResourceInputHandle`; scalar → `InputHandle<T>`. |
| `untypedOp` | `(id, op, { bind, config, guards? }) => void` | Escape hatch for ops not yet covered by a typed builder method. Accepts raw `Ref` values.            |
| `build`     | `() => TypedFlow<T>`                          | Serialises the builder state to a Flow document.                                                     |

### Op methods

The SDK exposes a typed method per op the Composer API supports. Examples:

* `builder.lifi.swap(id, args)`, `builder.lifi.zap(id, args)`
* `builder.core.call(id, args)`, `builder.core.asResource(id, args)`, `builder.core.balanceOf(id, args)`, and the arithmetic methods `builder.core.add(id, args)`, `subtract`, `multiply`, `divideDown`, `divideUp`, `bpsDown`, `bpsUp` — one method per arithmetic op.

Each method returns a typed `Record<portName, OutputHandle>` for the op's outputs. See the live [Ops catalog](/composer/composer-api/ops).

### `builder.compile(run)`

One-shot: calls `build()`, forms a `ComposeCompileRequest` via `sdk.request`, POSTs it to `/compose`, and returns a `ComposeCompileResult`.

```ts theme={"system"}
const result = await builder.compile({
  signer: '0xYourSigner',
  inputs: {
    amountIn: materialisers.directDeposit({ amount: '1000000000000000000' }),
  },
  sweepTo: builder.context.sender,
});
```

Throws a `ComposeError` on network, validation, or server errors.

## `sdk.request(flow, run)` → `ComposeCompileRequest`

Use when you need the raw request payload — queueing, server-side proxy, signing the request, inspection in tests.

```ts theme={"system"}
const flow = builder.build();
const request = sdk.request(flow, {
  signer: '0xYourSigner',
  inputs: { amountIn: materialisers.directDeposit({ amount: '1000000000000000000' }) },
});

const response = await fetch('https://composer.li.quest/compose', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify(request),
});
```

## `sdk.client`

The low-level HTTP client. Most integrations only need `builder.compile()`; reach for the client when you build a request via `sdk.request()` and submit it yourself, or when you need protocol/manifest discovery.

| Method        | Signature                                                               | Notes                                                                                                                                                                                                                                                                             |
| ------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `compile`     | `(request: ComposeCompileRequest) => Promise<ComposeCompileResult>`     | `POST /compose`. The transport `builder.compile()` calls under the hood.                                                                                                                                                                                                          |
| `getManifest` | `() => Promise<ComposeManifest>`                                        | `GET /compose/manifest`. The live catalog of ops, materialisers, and guards the backend accepts — the same source that powers the [Ops](/composer/composer-api/ops), [Materialisers](/composer/composer-api/materialisers), and [Guards](/composer/composer-api/guards) catalogs. |
| `getZapPacks` | `(options?: GetZapPacksOptions) => Promise<readonly ZapPackOverview[]>` | `GET /compose/zap-packs`. The dynamic routing-edge catalog — which tokens can be routed into which protocol positions on which chains. Use it to discover valid `lifi.zap` `resourceOut` targets.                                                                                 |

```ts theme={"system"}
// Discover which tokens can be zapped into Aave positions.
const packs = await sdk.client.getZapPacks({ protocols: 'aave' });
for (const pack of packs) {
  for (const edge of pack.edges) {
    // edge.type ('enter-position' | 'exit-position' | …), edge.in, edge.out
  }
}
```

`getZapPacks` accepts an optional `{ protocols?: string | readonly string[] }` filter. Results are not cached by the SDK — cache as appropriate for your refresh needs. See the [routing edges catalog](/composer/protocols-and-chains) for the rendered live view.

## `ComposeCompileResult`

A **discriminated union** on the `status` field. Branch on `result.status` before accessing shape-specific fields.

```ts theme={"system"}
type ComposeCompileResult =
  | (ComposeCompileSuccessData & { status: 'success' })
  | (ComposeCompilePartialData  & {
      status: 'partial';
      error: { kind: ComposeErrorKind; message: string };
      simulationRevert: SimulationRevert;
    });
```

* **`status: 'success'`** — returned under the default `simulationPolicy: 'strict'` when the compile and simulation both succeed.
* **`status: 'partial'`** — returned only when `simulationPolicy: 'allow-revert'` was passed on the run *and* the simulation reverted. The `transactionRequest` is still present; the revert diagnostics are exposed for the caller to surface.

Both shapes carry the core fields: `transactionRequest`, `userProxy`, `producedResources`, `producedHandles` (values for any output handles marked `expose: true`), optional `approvals`, optional `priceImpact`, and optional `fees`.

## `ComposeRunInput<T>`

Declared in [`run/inputs.ts`](https://unpkg.com/browse/@lifi/composer-sdk/src/run/inputs.ts).

| Field                    | Type                                    | Notes                                                                                                                                                                                         |
| ------------------------ | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `inputs`                 | `{ [K in keyof T]: InputSpecOf<T[K]> }` | Per-input value — `bigint`, hex string, or materialiser descriptor.                                                                                                                           |
| `signer`                 | `Address`                               | `0x`-prefixed signer address.                                                                                                                                                                 |
| `preconditions`          | `readonly Precondition[]?`              | Invariants asserted before execution.                                                                                                                                                         |
| `assumptions`            | `{ [K in keyof T]?: bigint }?`          | Assumed amounts when materialisers resolve at execution time.                                                                                                                                 |
| `referrer`               | `string?`                               | Integrator referrer id.                                                                                                                                                                       |
| `integratorFeeBps`       | `number?`                               | Integrator fee in basis points (1bp = 0.01%, max `9000`). Defaults to `0`. A non-zero value requires an integration-scoped API key — the integration is derived from the key, not this field. |
| `maxPriceImpactBps`      | `number?`                               | Reject compile if aggregate USD price impact exceeds the bound.                                                                                                                               |
| `sweepTo`                | `SweepTo?`                              | Destination for terminal proxy-held resources. Address literal or `{ $ref: "context.sender" }`.                                                                                               |
| `simulationPolicy`       | `"strict" \| "allow-revert"?`           | Default `"strict"`.                                                                                                                                                                           |
| `checkOnChainAllowances` | `boolean?`                              | Omit approvals already satisfied on-chain.                                                                                                                                                    |

## Handles

Declared in [`authoring/handles.ts`](https://unpkg.com/browse/@lifi/composer-sdk/src/authoring/handles.ts).

* **`InputHandle<T>`** — `{ _tag: 'input', inputName, __outputKind?: T }`. Carries the input's output kind as a phantom type parameter.
* **`ResourceInputHandle`** — `InputHandle<'resource'> & { resource: Resource }`.
* **`OutputHandle<T>`** — `{ _tag: 'output', nodeId, portName, __outputKind?: T }`.
* **`Bindable<T>`** — the union of values accepted in a typed bind slot: `InputHandle<T>`, `OutputHandle<T>`, `TypedRef<T>`. For `'uint256'` slots, `'resource'`-tagged handles are also accepted (resources are uint256 amounts).

Convert handles to raw refs with `handleToRef` (exported from the same module).

## Namespaces

* **`resources`** — helpers to declare token resources (`resources.erc20(token, chainId)`, `resources.native(chainId)`).
* **`materialisers`** — generated helpers for registered materialisers (`materialisers.directDeposit({ amount })`, `materialisers.balanceOf({ ... })`, …).
* **`guards`** — generated helpers for registered guards (`guards.slippage({ port, bps })`, …).
* **`raw`** — low-level escape hatches: `raw.ref<T>(path)` creates a `TypedRef<T>`; `raw.guard(kind, config?)` builds an `AppliedGuard` for guard kinds not yet covered by a typed helper; `raw.materialiser(kind, config?)` builds a `MaterialiserInput` for the same reason.

## `TypedFlow<T>`

The Flow document returned by `builder.build()`. Structurally identical to `Flow` from `@lifi/compose-spec`, with a phantom `__inputs?: T` carrying the input schema through TypeScript inference (`__inputs` does not exist at runtime).

## Error types

`ComposeError` (re-exported from `@lifi/compose-spec`) carries:

```ts theme={"system"}
{
  kind: ComposeErrorKind;   // e.g. "validation_error" | "guard_error" | "simulation_revert" | …
  message: string;
  path?: string;
}
```

See [Error codes](/composer/composer-api/reference/error-codes) for the full catalog and the HTTP status each kind maps to.

## See also

* [Quickstart](/composer/composer-api/quickstart) — five-minute first-flow walkthrough.
* [Build a Flow](/composer/composer-api/guides/build-a-flow) — production setup, inputs, ops, materialisers, guards, preconditions, submission.
* [Flow wire format](/composer/composer-api/reference/flow-wire-format) — the JSON the SDK produces.
