> ## 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 Integration

> Use the LI.FI TypeScript SDK for managed Composer execution with automatic allowance handling, status tracking, hooks, and events.

The LI.FI SDK handles the full Composer lifecycle (allowance checks, chain switching, transaction submission, and status tracking) so you can focus on your application logic. This guide shows how to use Composer through the SDK.

<Note>
  **Prerequisites:** You should have the LI.FI SDK installed and configured. If
  not, see [Installing the SDK](/sdk/installing-the-sdk) and [Configure
  SDK](/sdk/configure-sdk).
</Note>

***

## Quick Example

Deposit USDC into a Morpho vault on Base using the SDK:

```ts theme={"system"}
import {
  createClient,
  getQuote,
  convertQuoteToRoute,
  executeRoute,
} from "@lifi/sdk";

// 1. Configure the SDK (once, at app startup)
const client = createClient({
  integrator: "YourAppName",
});

// 2. Get a Composer quote
const quote = await getQuote(client, {
  fromChain: 8453, // Base
  toChain: 8453, // Base
  fromToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC on Base
  toToken: "0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A", // Morpho vault token
  fromAmount: "1000000", // 1 USDC
  fromAddress: "0xYOUR_WALLET_ADDRESS",
});

// 3. Convert quote to route and execute - SDK handles allowance, submission, and tracking
const route = convertQuoteToRoute(quote);
const executedRoute = await executeRoute(client, route, {
  updateRouteHook(updatedRoute) {
    console.log("Route updated:", updatedRoute);
  },
});

console.log("Done!", executedRoute);
```

That's it. The SDK internally manages:

* **Allowance checks and approvals**
* **Transaction data retrieval** (if using `/advanced/routes`)
* **Transaction submission**
* **Status tracking and polling**
* **Chain switching** (for cross-chain flows)

***

## Step-by-Step Guide

### 1. Configure the SDK

Set up the SDK once at application startup. You must configure [EVM providers](/sdk/configure-sdk-providers#setup-evm-provider) for the chains you want to use.

```ts theme={"system"}
import { createClient } from "@lifi/sdk";
import { EthereumProvider } from "@lifi/sdk-provider-ethereum";

const client = createClient({
  integrator: "YourAppName",
});

client.setProviders([
  EthereumProvider({
    getWalletClient: () => Promise.resolve(walletClient),
  }),
]);
```

For full provider configuration, see [Configure SDK Providers](/sdk/configure-sdk-providers).

### 2. Request a Composer Quote

Use `getQuote` for a single best route (includes transaction data) or `getRoutes` for multiple options.

#### Using `getQuote`

```ts theme={"system"}
import { getQuote } from "@lifi/sdk";

const quote = await getQuote(client, {
  fromChain: 8453,
  toChain: 8453,
  fromToken: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
  toToken: "0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A",
  fromAmount: "1000000",
  fromAddress: "0xYOUR_WALLET_ADDRESS",
});
```

#### Using `getRoutes`

```ts theme={"system"}
import { getRoutes } from "@lifi/sdk";

const result = await getRoutes(client, {
  fromChainId: 8453,
  toChainId: 8453,
  fromTokenAddress: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
  toTokenAddress: "0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A",
  fromAmount: "1000000",
  fromAddress: "0xYOUR_WALLET_ADDRESS",
});

const route = result.routes[0]; // Select the best route
```

<Tip>
  The `toToken` / `toTokenAddress` is always the **vault token address** of the
  target protocol. This is what triggers Composer. Find vault token addresses on
  the protocol's own app or documentation.
</Tip>

### 3. Execute the Route

The `executeRoute` function handles the entire execution lifecycle:

```ts theme={"system"}
import { executeRoute } from "@lifi/sdk";

const executedRoute = await executeRoute(client, route, {
  // Called whenever the route object is updated during execution
  updateRouteHook(updatedRoute) {
    const step = updatedRoute.steps[0];
    const actions = step?.execution?.actions;
    const lastAction = actions?.[actions.length - 1];

    console.log(`Step: ${step?.tool}`);
    console.log(`Status: ${lastAction?.status}`);
    console.log(`Tx: ${lastAction?.txHash || "pending"}`);
  },
});
```

### 4. Monitor Execution

The `updateRouteHook` callback fires on every state change. Use it to update your UI:

```ts theme={"system"}
const executedRoute = await executeRoute(client, route, {
  updateRouteHook(updatedRoute) {
    for (const step of updatedRoute.steps) {
      if (!step.execution) continue;

      for (const action of step.execution.actions) {
        switch (action.status) {
          case "STARTED":
            console.log(`${action.type} started`);
            break;
          case "PENDING":
            console.log(`${action.type} pending - tx: ${action.txHash}`);
            break;
          case "DONE":
            console.log(`${action.type} complete`);
            break;
          case "FAILED":
            console.error(`${action.type} failed: ${action.error?.message}`);
            break;
        }
      }
    }
  },
});
```

***

## Cross-Chain Composer via SDK

Cross-chain Composer works across EVM chains. The integration is identical to same-chain: just use different `fromChain` and `toChain` values. The SDK handles bridge routing, chain switching, and status tracking automatically.

### ETH (Ethereum) → Morpho vault (Base)

```ts theme={"system"}
const crossChainQuote = await getQuote(client, {
  fromChain: 1, // Ethereum
  toChain: 8453, // Base
  fromToken: "0x0000000000000000000000000000000000000000", // ETH (native)
  toToken: "0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A", // Morpho vault on Base
  fromAmount: "100000000000000000", // 0.1 ETH
  fromAddress: "0xYOUR_WALLET_ADDRESS",
});

const route = convertQuoteToRoute(crossChainQuote);
const executedRoute = await executeRoute(client, route, {
  updateRouteHook(updatedRoute) {
    console.log(
      "Route updated:",
      updatedRoute.steps.map((s) => s.tool),
    );
  },
});
```

### USDC (Ethereum) → Morpho Vault (Base)

```ts theme={"system"}
const crossChainQuote = await getQuote(client, {
  fromChain: 1, // Ethereum
  toChain: 8453, // Base
  fromToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC on Ethereum
  toToken: "0x7BfA7C4f149E7415b73bdeDfe609237e29CBF34A", // Morpho vault on Base
  fromAmount: "1000000000", // 1000 USDC
  fromAddress: "0xYOUR_WALLET_ADDRESS",
  slippage: 0.01,
});

const route = convertQuoteToRoute(crossChainQuote);
const executedRoute = await executeRoute(client, route, {
  updateRouteHook(updatedRoute) {
    console.log(
      "Route updated:",
      updatedRoute.steps.map((s) => s.tool),
    );
  },
});
```

The SDK automatically handles:

* Bridge selection and execution
* Waiting for bridge completion
* Chain switching to the destination chain
* Executing the Composer deposit on the destination chain
* Status tracking throughout

***

## Execution Options

All execution options are optional but can be useful for advanced use cases:

| Option                         | Type                           | Description                                                                          |
| ------------------------------ | ------------------------------ | ------------------------------------------------------------------------------------ |
| `updateRouteHook`              | `(route) => void`              | Called on every route state change. Use for UI updates.                              |
| `updateTransactionRequestHook` | `(txRequest) => Promise<tx>`   | Modify transaction requests before submission (e.g., custom gas).                    |
| `acceptExchangeRateUpdateHook` | `(params) => Promise<boolean>` | Called if the exchange rate changes during execution. Return `true` to accept.       |
| `getContractCalls`             | `(params) => Promise<result>`  | Dynamically provide contract calls during execution based on actual bridged amounts. |
| `executeInBackground`          | `boolean`                      | If `true`, execution continues even if the user navigates away.                      |

For the full execution options reference, see [Execute Routes/Quotes](/sdk/execute-routes).

***

## Error Handling

The SDK throws errors that you can catch and handle:

```ts theme={"system"}
try {
  const executedRoute = await executeRoute(client, route, {
    updateRouteHook(updatedRoute) {
      // Track progress
    },
  });
} catch (error) {
  console.error("Execution failed:", error.message);

  // Check the route's step execution for detailed failure info
  for (const step of route.steps) {
    if (step.execution) {
      for (const action of step.execution.actions) {
        if (action.status === "FAILED") {
          console.error(`Step ${step.tool} failed:`, action.error?.message);
        }
      }
    }
  }
}
```

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Cross-Chain Patterns" icon="bridge" href="/composer/lifi-api/guides/cross-chain-compose">
    Advanced cross-chain Composer flows
  </Card>

  <Card title="Widget Integration" icon="window" href="/composer/lifi-api/guides/widget-integration">
    Zero-code Composer via the drop-in Widget
  </Card>

  <Card title="SDK Configuration" icon="gear" href="/sdk/configure-sdk">
    Full SDK configuration reference
  </Card>

  <Card title="Vault Deposit Recipes" icon="book" href="/composer/lifi-api/recipes/vault-deposits">
    Copy-paste recipes for common protocols
  </Card>
</CardGroup>
