# Swap Borrow Asset

Swapping borrow assets combines repay, swap, and re-borrow into one step.

> [!WARNING]
> Position swaps now run on the Order API. Update your code:
> - `preparePositionSwap` → `prepareOrder`
> - `swap` → `submitOrder`
> - React: `useSupplySwap` → `useSupplySwapOrder`
> - React: `useBorrowSwap` → `useBorrowSwapOrder`
> - React: `useRepayWithSupply` → `useRepayWithSupplyOrder`

This feature leverages [CoW Protocol](https://cow.fi/) for swap execution. Users sign an intent and solvers execute it through batch auctions with [MEV protection](https://ethereum.org/en/developers/docs/mev/). Most flows need no transaction; if an approval or the `submitOrder` result returns a transaction request, the user sends it and pays gas.

> [!NOTE]
> See [Fees](../../tools/swaps#fees) for swap costs.

Common scenarios:

| Scenario              | Description                                                                                               |
| --------------------- | --------------------------------------------------------------------------------------------------------- |
| **Rate Optimization**     | User wants to switch debt from a high-interest token to a lower-interest one (e.g., USDC → GHO)           |
| **Risk Management**       | User wants to match their debt currency to their income or collateral to reduce currency exposure         |
| **Liquidation Avoidance** | User wants to swap volatile debt (e.g., ETH-denominated) to stable debt (e.g., USDC) to avoid liquidation |

Swapping borrow assets can be broken down into the following steps:

1. Identify the borrow position to swap from
2. Choose the target reserve to swap onto
3. Choose between market order and limit order
4. Execute the swap operation

## Identify the Borrow Position

Identify the borrow position among the user’s [borrow positions](../fetch#fetching-user-borrows) where `reserve.canSwapFrom: true`.

```tsx title="UserBorrowItem"
const borrowPosition: UserBorrowItem = {
  id: "Ym9ycm93",
  reserve: {
    id: "SGVsbG8h",
    canSwapFrom: true,
    chain: {
      chainId: 1,
      name: "Ethereum",
    },
    spoke: {
      id: "aGVsbG8",
      // …
    },
    // …
  },
  debt: {
    amount: {
      value: BigDecimal(1000.0),
      exchange: {
        value: BigDecimal(1000.0),
        // …
      },
      // …
    },
    // …
  },
  principal: {
    amount: {
      value: BigDecimal(950.0),
      // …
    },
    // …
  },
  interest: {
    amount: {
      value: BigDecimal(50.0),
      // …
    },
    // …
  },
  // …
};
```

> [!NOTE]
> `reserve.canSwapFrom` means the reserve isn’t paused and has flash loans
> enabled, which the swap needs.

## Identify the Target Borrow Reserve

Choose the target [reserve](../../liquidity/reserves#listing-available-reserves) where `canBorrow: true`. The target reserve must be on the **same spoke** as the source borrow position.

> [!NOTE]
> As in a regular borrow, `canBorrow` means the reserve isn’t frozen, isn’t
> paused and is below its borrow cap.

```tsx title="Target Reserve"
const targetReserve: Reserve = {
  id: "V29ybGQh",
  canBorrow: true,
  spoke: {
    id: "aGVsbG8",
    // …
  },
  asset: {
    underlying: {
      address: "0x40d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f",
      info: {
        name: "GHO",
        symbol: "GHO",
        decimals: 18,
        // …
      },
      // …
    },
    // …
  },
  summary: {
    borrowApy: {
      normalized: BigDecimal(2.5), // 2.5% APY
      // …
    },
    // …
  },
  userState: {
    borrowable: {
      exchange: {
        value: BigDecimal(5000.0),
        name: "USD",
        symbol: "$",
        // …
      },
      // …
    },
  },
  // …
};
```

Consider the following factors when selecting a target reserve:

- **Token**: Check `asset.underlying` for the token of the new debt position
- **Capacity**: Review `userState.borrowable` for sufficient borrow capacity
- **Rate**: Compare `summary.borrowApy` for favorable borrowing rates

## Market or Limit Order

You decide whether to use a market order or a limit order.

### Market Orders

Market orders execute at current rates.

```ts title="TypeScript"
const request: BorrowSwapQuoteRequest = {
  market: {
    debtPosition: borrowPosition.id,
    buyReserve: targetReserve.id,
    amount: bigDecimal(1000),
    user: evmAddress("0x123…"),
    // selectedSlippage: bigDecimal(1), // Optional: override suggested slippage
  },
};
```

```json title="GraphQL Variables"
{
  "request": {
    "market": {
      "debtPosition": "Ym9ycm93",
      "buyReserve": "V29ybGQh",
      "amount": "1000",
      "user": "0x123…"
    }
  }
}
```

The request takes the following parameters:

- `debtPosition`: The current borrow position to swap from
- `buyReserve`: The target reserve to swap to
- `amount`: The amount of the current debt to swap
- `user`: The user’s address
- `selectedSlippage`: Optional slippage tolerance to use instead of the suggested slippage

### Limit Orders

Limit orders execute when your price condition is met.

```ts title="TypeScript"
const request: BorrowSwapQuoteRequest = {
  limit: {
    currentPosition: borrowPosition.id,
    currentAmount: bigDecimal(1000),
    newReserve: targetReserve.id,
    newAmount: bigDecimal(1050), // Desired amount of new debt
    user: evmAddress("0x123…"),
    kind: BorrowSwapKind.Current,
    // deadline: new Date(Date.now() + 24 * 60 * 60 * 1000), // Optional: custom expiry
  },
};
```

```json title="GraphQL Variables"
{
  "request": {
    "limit": {
      "currentPosition": "Ym9ycm93",
      "currentAmount": "1000",
      "newReserve": "V29ybGQh",
      "newAmount": "1050",
      "user": "0x123…",
      "kind": "CURRENT"
    }
  }
}
```

The request takes the following parameters:

- `currentPosition`: The current borrow position to swap from
- `currentAmount`: The amount of the current debt to repay
- `newReserve`: The target reserve to swap to
- `newAmount`: The desired amount of new debt to take on
- `user`: The user’s address
- `kind`: Current (default) or New, determines which amount is honored
- `deadline`: Optional deadline as DateTime; if not provided, uses default expiry

With both amounts specified, the `kind` parameter determines which amount takes priority:

| Kind    | User specifies…                                                | What happens with the order                                                              |
| ------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| **Current** | The exact _current_ debt repaid and a maximum _new_ debt amount | Order fulfilled when the full current debt can be repaid without exceeding the new debt |
| **New**     | The exact _new_ debt amount and a minimum _current_ debt repaid | Order fulfilled when the new debt repays at least the specified current debt            |

## Step-by-Step with AaveKit

To execute a borrow swap with AaveKit, follow these steps.

### 1. Get a Quote

First, use the `useBorrowSwapQuote` hook (or the imperative `useBorrowSwapQuoteAction` variant) in React, the `borrowSwapQuote` action in TypeScript, or the `borrowSwapQuote` query in GraphQL to get pricing information for the swap.

<tabgroup>
<tab label="React">

```tsx title="Loading State"
import { type BorrowSwapQuoteRequest, useBorrowSwapQuote } from "@aave/react";

function SwapQuote({ request }: { request: BorrowSwapQuoteRequest }) {
  const { data, loading, error } = useBorrowSwapQuote(request);

  if (loading) return Loading…;

  if (error) {
    if (error.name === "ValidationError") {
      switch (error.cause.__typename) {
        case "InsufficientLiquidityError":
          return Not enough liquidity for this swap;
      }
    }
    return {error.message};
  }

  // data: SwapQuote
  return (
    <div>
      New debt amount: {data.finalBuy.amount.value.toDisplayString()}
      Partner fee: {data.costs.partnerFee.amount.value.toDisplayString()}
      Slippage: {data.suggestedSlippage.normalized}%
    </div>
  );
}
```

```tsx title="React Suspense"
import { type BorrowSwapQuoteRequest, useBorrowSwapQuote } from "@aave/react";

function SwapQuote({ request }: { request: BorrowSwapQuoteRequest }) {
  const { data } = useBorrowSwapQuote({
    ...request,
    suspense: true,
  });

  // data: SwapQuote
  return (
    <div>
      New debt amount: {data.finalBuy.amount.value.toDisplayString()}
      Partner fee: {data.costs.partnerFee.amount.value.toDisplayString()}
      Slippage: {data.suggestedSlippage.normalized}%
    </div>
  );
}
```

```tsx title="Imperative Read"
import {
  type BorrowSwapQuoteRequest,
  useBorrowSwapQuoteAction,
} from "@aave/react";

const [getQuote, { called, data, error, loading }] = useBorrowSwapQuoteAction();

const handler = async (request: BorrowSwapQuoteRequest) => {
  const result = await getQuote(request);

  if (result.isOk()) {
    // result.value: SwapQuote
    console.log(result.value);
  } else {
    console.error(result.error);
  }
};
```

</tab>
<tab label="TypeScript">

```ts title="Get Quote"
import { borrowSwapQuote } from "@aave/client/actions";

import { client } from "./client";

// …

const result = await borrowSwapQuote(client, request);

if (result.isErr()) {
  console.error(result.error);
  return;
}

// result.value.quote: SwapQuote
```

```ts title="client.ts"
import { AaveClient } from "@aave/client";

export const client = AaveClient.create();
```

</tab>
<tab label="GraphQL">

```graphql title="Query"
query ($request: BorrowSwapQuoteRequest!, $currency: Currency!) {
  borrowSwapQuote(request: $request) {
    __typename
    ... on PositionSwapByIntentApprovalsRequired {
      quote {
        ...SwapQuote
      }
      approvals {
        ...PositionSwapApproval
      }
    }
    ... on InsufficientLiquidityError {
      reason
    }
  }
}
```

```graphql title="PositionSwapApproval"
fragment PositionSwapApproval on PositionSwapApproval {
  __typename
  ... on PositionSwapAdapterContractApproval {
    bySignature {
      ...SwapTypedData
    }
  }
  ... on PositionSwapPositionManagerApproval {
    byTransaction {
      ...TransactionRequest
    }
    bySignature {
      ...SwapTypedData
    }
  }
  ... on PositionSwapSetCollateralApproval {
    bySignature {
      ...SwapTypedData
    }
  }
}
```

</tab>
</tabgroup>
In React and TypeScript, you can specify a different currency to return fiat amounts in.

<tabgroup>
<tab label="React">

```ts title="useBorrowSwapQuote"
import { Currency } from "@aave/react";

const { data, error, loading } = useBorrowSwapQuote({
  ...request,
  currency: Currency.Eur,
});
```

```ts title="useBorrowSwapQuoteAction"
import { Currency } from "@aave/react";

const [getQuote, { called, data, error, loading }] = useBorrowSwapQuoteAction({
  currency: Currency.Eur,
});
```

</tab>
<tab label="TypeScript">

```ts title="Custom Currency"
import { Currency } from "@aave/client";

// …

const result = await borrowSwapQuote(client, request, {
  currency: Currency.Eur,
});
```

</tab>
</tabgroup>
In React and TypeScript, the quote is returned as a `SwapQuote`.

In GraphQL, the response can be either:

- `PositionSwapByIntentApprovalsRequired`: The quote was successful, but the user needs to sign approvals before executing the swap.
- `InsufficientLiquidityError`: There’s not enough liquidity for the requested swap amount.

The `PositionSwapByIntentApprovalsRequired` contains the `SwapQuote` with pricing details and the `PositionSwapApproval` list of required approvals to sign before executing the swap.

### 2. Preview the Impact

Then, use the `usePreview` hook (or the imperative `usePreviewAction` variant) in React, the `preview` action in TypeScript, or the `preview` query with the `quoteId` from the previous step in GraphQL to preview the impact of the swap operation on the user’s position. In TypeScript and GraphQL, this step is optional.

<tabgroup>
<tab label="React">

```tsx title="Loading State"
import { type SwapQuote, usePreview } from "@aave/react";

function SwapPreview({ quote }: { quote: SwapQuote }) {
  const { data, error, loading } = usePreview({
    action: {
      borrowSwap: {
        fromQuote: {
          quoteId: quote.quoteId,
        },
      },
    },
  });

  if (loading) return <div>Loading…</div>;
  if (error) return <div>Error: {error.message}</div>;

  // data: PreviewUserPosition
  return (
    <div>
      <h3>Health Factor:</h3>
      From: {data.healthFactor.current?.toFixed(2) ?? "N/A"}
      To: {data.healthFactor.after?.toFixed(2) ?? "N/A"}

      <h3>User Risk Premium:</h3>
      From: {data.riskPremium.current.normalized.toFixed(2)}%
      To: {data.riskPremium.after.normalized.toFixed(2)}%

      <h3>Net APY:</h3>
      From: {data.netApy.current.normalized.toFixed(2)}%
      To: {data.netApy.after.normalized.toFixed(2)}%

      <h3>Net Collateral:</h3>
      From: {data.netCollateral.current.value.toDisplayString(2)}
      To: {data.netCollateral.after.value.toDisplayString(2)}

      <h3>Max Borrowing Power:</h3>
      From: {data.maxBorrowingPower.current.value.toDisplayString(2)}
      To: {data.maxBorrowingPower.after.value.toDisplayString(2)}
    </div>
  );
}
```

```tsx title="React Suspense"
import { type SwapQuote, usePreview } from "@aave/react";

function SwapPreview({ quote }: { quote: SwapQuote }) {
  const { data, error, loading } = usePreview({
    action: {
      borrowSwap: {
        fromQuote: {
          quoteId: quote.quoteId,
        },
      },
    },
    suspense: true,
  });

  // data: PreviewUserPosition
  return (
    <div>
      <h3>Health Factor:</h3>
      From: {data.healthFactor.current?.toFixed(2) ?? "N/A"}
      To: {data.healthFactor.after?.toFixed(2) ?? "N/A"}

      <h3>User Risk Premium:</h3>
      From: {data.riskPremium.current.normalized.toFixed(2)}%
      To: {data.riskPremium.after.normalized.toFixed(2)}%

      <h3>Net APY:</h3>
      From: {data.netApy.current.normalized.toFixed(2)}%
      To: {data.netApy.after.normalized.toFixed(2)}%

      <h3>Net Collateral:</h3>
      From: {data.netCollateral.current.value.toDisplayString(2)}
      To: {data.netCollateral.after.value.toDisplayString(2)}

      <h3>Max Borrowing Power:</h3>
      From: {data.maxBorrowingPower.current.value.toDisplayString(2)}
      To: {data.maxBorrowingPower.after.value.toDisplayString(2)}
    </div>
  );
}
```

```tsx title="Imperative Read"
import { type SwapQuote, usePreviewAction } from "@aave/react";

// …

const [preview, { called, data, error, loading }] = usePreviewAction();

const handler = async (quote: SwapQuote) => {
  const result = await preview({
    action: {
      borrowSwap: {
        fromQuote: {
          quoteId: quote.quoteId,
        },
      },
    },
  });

  if (result.isOk()) {
    console.log(result.value); // PreviewUserPosition
  } else {
    console.error(result.error);
  }
};
```

</tab>
<tab label="TypeScript">

```ts title="Preview Swap"
import { preview } from "@aave/client/actions";
import { client } from "./client";

// …

const result = await borrowSwapQuote(client, request).andThen(
  ({ approvals, quote }) =>
    preview(client, {
      action: {
        borrowSwap: {
          fromQuote: {
            quoteId: quote.quoteId,
          },
        },
      },
    }),
);

if (result.isErr()) {
  console.error(result.error);
  return;
}

// result.value: PreviewUserPosition
```

</tab>
<tab label="GraphQL">

```graphql title="Query"
query ($request: PreviewRequest!, $currency: Currency = USD) {
  preview(request: $request) {
    __typename
    id
    healthFactor {
      ...HealthFactorResult
    }
    netApy {
      ...PercentNumberVariation
    }
    riskPremium {
      ...PercentNumberVariation
    }
    netCollateral(currency: $currency) {
      ...ExchangeAmountVariation
    }
    netBalance(currency: $currency) {
      ...ExchangeAmountVariation
    }
    projectedEarnings {
      ...ExchangeAmountVariation
    }
    maxBorrowingPower {
      ...ExchangeAmountVariation
    }
    remainingBorrowingPower {
      ...ExchangeAmountVariation
    }
    otherConditions {
      ...UserPositionConditionVariation
    }
  }
}
```

</tab>
</tabgroup>
In GraphQL, pass the `quoteId` in the `borrowSwap.fromQuote` field:

<tabgroup>
<tab label="GraphQL">

```json title="Variables"
{
  "request": {
    "action": {
      "borrowSwap": {
        "fromQuote": {
          "quoteId": "<quote-id-from-step-1>"
        }
      }
    }
  },
  "currency": "USD"
}
```

</tab>
</tabgroup>
The `PreviewUserPosition` shows the impact of the swap operation by comparing current and after states, with the table below outlining key fields and how to interpret them.

### 3. Configure Wallet Integration

Then, in React, instantiate the hooks for the [wallet library of your choice](../../getting-started/react#integrations):

- `useSignTypedData`: used to sign the approvals and the order typed data
- `useSendTransaction`: used to send the order transaction when the Order API returns one

<tabgroup>
<tab label="React">

```tsx title="Viem"
import { useWalletClient } from "wagmi";
import { useSendTransaction, useSignTypedData } from "@aave/react/viem";

// …

const { data: wallet } = useWalletClient();
const [sendTransaction] = useSendTransaction(wallet);
const [signTypedData] = useSignTypedData(wallet);
```

</tab>
</tabgroup>
### 4. Define the Swap Flow

Then, in React, use the `useBorrowSwapOrder` hook to handle the operation. It fetches the quote, collects the approval signatures, and prepares, signs, and submits the order.

<tabgroup>
<tab label="React">

```tsx title="Basic Usage"
import { useBorrowSwapOrder } from "@aave/react";

const [swapBorrow, { loading, error }] = useBorrowSwapOrder((plan) => {
  switch (plan.__typename) {
    case "PositionSwapAdapterContractApproval":
    case "PositionSwapPositionManagerApproval":
    case "PositionSwapSetCollateralApproval":
      return signTypedData(plan.bySignature);

    case "OrderTypedData":
      return signTypedData(plan);

    case "OrderTransactionRequest":
      return sendTransaction(plan.transaction);
  }
});
```

```tsx title="Update Component State"
import { useState } from "react";
import { useBorrowSwapOrder } from "@aave/react";

const [status, setStatus] = useState("");

const [swapBorrow, { loading, error }] = useBorrowSwapOrder((plan) => {
  switch (plan.__typename) {
    case "PositionSwapAdapterContractApproval":
      setStatus("Sign the swap adapter approval in your wallet");
      return signTypedData(plan.bySignature);

    case "PositionSwapPositionManagerApproval":
      setStatus("Sign the swap position manager approval in your wallet");
      return signTypedData(plan.bySignature);

    case "PositionSwapSetCollateralApproval":
      setStatus("Sign the set collateral approval in your wallet");
      return signTypedData(plan.bySignature);

    case "OrderTypedData":
      setStatus("Sign the swap order in your wallet");
      return signTypedData(plan);

    case "OrderTransactionRequest":
      setStatus("Send the swap transaction in your wallet");
      return sendTransaction(plan.transaction);
  }
});
```

```tsx title="Cancel Flow"
import { useBorrowSwapOrder } from "@aave/react";

const [swapBorrow, { loading, error }] = useBorrowSwapOrder((plan, { cancel }) => {
  if (window.confirm("Are you sure you want to continue?") === false) {
    return cancel("User cancelled the operation");
  }

  switch (plan.__typename) {
    case "PositionSwapAdapterContractApproval":
    case "PositionSwapPositionManagerApproval":
    case "PositionSwapSetCollateralApproval":
      return signTypedData(plan.bySignature);

    case "OrderTypedData":
      return signTypedData(plan);

    case "OrderTransactionRequest":
      return sendTransaction(plan.transaction);
  }
});
```

</tab>
</tabgroup>
The operation involves up to 3 signatures:

- **Swap adapter contract approval**: A one-time-use contract that encapsulates the swap logic. This signature ensures the contract is used only once for this specific swap operation.
- **Swap position manager approval**: Authorizes a dedicated [Position Manager](../managers) to operate on the user’s position.
- **Swap order**: The order typed data returned by `prepareOrder`, signed after the approvals.

### 5. Sign Approvals

In TypeScript, use `signTypedDataWith` for the [wallet library of your choice](../../getting-started/typescript#sign-typed-data) to sign the swap approvals.

<tabgroup>
<tab label="TypeScript">

```ts title="signApprovals.ts"
import {
  type PositionSwapByIntentApprovalsRequired,
  type PrepareOrderRequest,
  type ResultAsync,
  type SignTypedDataError,
  okAsync,
} from "@aave/client";
import { signTypedDataWith } from "@aave/client/viem";

import { wallet } from "./wallet";

export function signApprovals({
  approvals,
  quote,
}: PositionSwapByIntentApprovalsRequired): ResultAsync<
  PrepareOrderRequest,
  SignTypedDataError
> {
  return approvals.reduce(
    (acc, approval) =>
      acc.andThen((request) =>
        signTypedDataWith(wallet, approval.bySignature).map((signature) => {
          switch (approval.__typename) {
            case "PositionSwapAdapterContractApproval":
              return { ...request, adapterContractSignature: signature };
            case "PositionSwapPositionManagerApproval":
              return { ...request, positionManagerSignature: signature };
            case "PositionSwapSetCollateralApproval":
              return { ...request, setCollateralSignature: signature };
          }
        }),
      ),
    okAsync<PrepareOrderRequest, SignTypedDataError>({
      quoteId: quote.orderQuoteId,
      adapterContractSignature: null,
      positionManagerSignature: null,
      setCollateralSignature: null,
    }),
  );
}
```

```ts title="wallet.ts"
import { createWalletClient, http, type Hex } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { mainnet } from "viem/chains";

export const wallet = createWalletClient({
  account: privateKeyToAccount(process.env.PRIVATE_KEY as Hex),
  chain: mainnet,
  transport: http(),
});
```

</tab>
</tabgroup>
In GraphQL, handle the required approvals from the quote response before proceeding:

- `PositionSwapAdapterContractApproval`: Sign the `bySignature` typed data to authorize the swap adapter contract.
- `PositionSwapPositionManagerApproval`: Either send the `byTransaction` request or sign the `bySignature` typed data to authorize the position manager.

### 6. Prepare the Order

- **TypeScript**: Use the `prepareOrder` action to prepare the order.
- **GraphQL**: Use the `prepareOrder` query with the quote’s `orderQuoteId` and the signed approvals.

<tabgroup>
<tab label="TypeScript">

```ts title="Prepare Order"
import { prepareOrder } from "@aave/client/actions";

import { signApprovals } from "./signApprovals";

// …

const result = await borrowSwapQuote(client, request)
  .andThen(signApprovals)
  .andThen((request) => prepareOrder(client, request));

if (result.isErr()) {
  console.error(result.error);
  return;
}

// result.value: PreparedOrder
```

</tab>
<tab label="GraphQL">

```graphql title="Query"
query ($request: PrepareOrderRequest!) {
  prepareOrder(request: $request) {
    __typename
    ... on PreparedOrder {
      ...PreparedOrder
    }
    ... on InsufficientBalanceError {
      ...InsufficientBalanceError
    }
  }
}
```

```graphql title="PreparedOrder"
fragment PreparedOrder on PreparedOrder {
  __typename
  newQuoteId
  data {
    ...OrderTypedData
  }
}
```

```graphql title="OrderTypedData"
fragment OrderTypedData on OrderTypedData {
  __typename
  types
  primaryType
  domain {
    ...DomainData
  }
  message
}
```

</tab>
</tabgroup>
With the `orderQuoteId` from the last quote response and the signed approvals, construct the request as follows:

<tabgroup>
<tab label="GraphQL">

```json title="Both Approvals by Signature"
{
  "request": {
    "quoteId": "<quote.orderQuoteId>",
    "adapterContractSignature": "0x…",
    "positionManagerSignature": "0x…"
  }
}
```

```json title="Position Manager Approval by Transaction"
{
  "request": {
    "quoteId": "<quote.orderQuoteId>",
    "adapterContractSignature": "0x…"
  }
}
```

```json title="No Approvals Needed"
{
  "request": {
    "quoteId": "<quote.orderQuoteId>"
  }
}
```

</tab>
</tabgroup>
If the response is a `PreparedOrder`, sign the `data` typed data and submit the order. If it’s an `InsufficientBalanceError`, inform the user about the insufficient balance.

### 7. Execute the Swap

Then, execute the swap for the given quote.

- **TypeScript**: Sign the order typed data and submit it with the `submitOrder` action. If the response is an `OrderTransactionRequest`, send the transaction with `sendWith`.
- **GraphQL**: Use the `submitOrder` mutation with the new quote ID and the signed order from the previous step.

<tabgroup>
<tab label="React">

```tsx title="Execute"
const execute = async (quote: SwapQuote) => {
  const result = await swapBorrow({
    fromQuote: {
      quoteId: quote.quoteId,
    },
  });

  if (result.isErr()) {
    console.error(result.error);
    return;
  }

  // result.value: OrderReceipt
  console.log("Swap order placed:", result.value.orderId);
};
```

</tab>
<tab label="TypeScript">

```ts title="Execute Swap"
import { okAsync } from "@aave/client";
import { prepareOrder, submitOrder, borrowSwapQuote } from "@aave/client/actions";
import { sendWith, signTypedDataWith } from "@aave/client/viem";

import { client } from "./client";
import { signApprovals } from "./signApprovals";
import { wallet } from "./wallet";

const result = await borrowSwapQuote(client, request)
  .andThen(signApprovals)
  .andThen((request) => prepareOrder(client, request))
  .andThen(({ newQuoteId, data }) =>
    signTypedDataWith(wallet, data).andThen((signature) =>
      submitOrder(client, { bySignature: { quoteId: newQuoteId, signature } }),
    ),
  )
  .andThen((plan) => {
    switch (plan.__typename) {
      case "OrderTransactionRequest":
        return sendWith(wallet, plan.transaction).map(() => plan.orderReceipt);
      case "OrderReceipt":
        return okAsync(plan);
    }
  });

// …
```

```ts title="wallet.ts"
import { createWalletClient, http, type Hex } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { mainnet } from "viem/chains";

export const wallet = createWalletClient({
  account: privateKeyToAccount(process.env.PRIVATE_KEY as Hex),
  chain: mainnet,
  transport: http(),
});
```

</tab>
<tab label="GraphQL">

```graphql title="Mutation"
mutation ($request: SubmitOrderRequest!) {
  submitOrder(request: $request) {
    __typename
    ... on OrderTransactionRequest {
      ...OrderTransactionRequest
    }
    ... on OrderReceipt {
      ...OrderReceipt
    }
    ... on InsufficientBalanceError {
      ...InsufficientBalanceError
    }
  }
}
```

```graphql title="OrderTransactionRequest"
fragment OrderTransactionRequest on OrderTransactionRequest {
  __typename
  transaction {
    ...TransactionRequest
  }
  orderReceipt {
    ...OrderReceipt
  }
}
```

```graphql title="OrderReceipt"
fragment OrderReceipt on OrderReceipt {
  __typename
  orderId
}
```

</tab>
</tabgroup>
In GraphQL, pass the `newQuoteId` from the `prepareOrder` response and the signed order as variables:

<tabgroup>
<tab label="GraphQL">

```json title="Variables"
{
  "request": {
    "bySignature": {
      "quoteId": "<prepareOrder.newQuoteId>",
      "signature": "0x…"
    }
  }
}
```

</tab>
</tabgroup>
### 8. Handle the Result

Finally, in React and TypeScript, handle the result.

<tabgroup>
<tab label="React">

```tsx title="Handle Result"
if (result.isErr()) {
  switch (result.error.name) {
    case "CancelError":
      return;

    case "SigningError":
      console.error(`Failed to sign: ${result.error.message}`);
      break;

    case "TimeoutError":
      console.error(`Timed out: ${result.error.message}`);
      break;

    case "TransactionError":
      console.error(`Failed: ${result.error.message}`);
      break;

    case "ValidationError":
      switch (result.error.cause.__typename) {
        case "InsufficientBalanceError":
          console.error(
            "Insufficient balance:",
            `required: ${result.error.cause.required.value.toDisplayString(2)}`,
            `available: ${result.error.cause.available.value.toDisplayString(2)}`,
          );
          break;
        case "InsufficientLiquidityError":
          console.error(`Insufficient liquidity: ${result.error.cause.reason}`);
          break;
      }
      break;

    case "UnexpectedError":
      console.error(result.error.message);
      break;
  }
  return;
}

// result.value: OrderReceipt
console.log("Swap order placed:", result.value.orderId);
```

</tab>
<tab label="TypeScript">

```ts title="Handle Result"
// …

if (result.isErr()) {
  console.error(result.error);
  return;
}

// result.value: OrderReceipt
console.log("Swap order placed:", result.value.orderId);
```

</tab>
</tabgroup>
In GraphQL, process the response based on the `__typename`:

- `OrderReceipt`: The order was placed. Use the `orderId` to track its status.
- `OrderTransactionRequest`: Send the `transaction` request, then track the order using `orderReceipt.orderId`.
- `InsufficientBalanceError`: Inform the user about the insufficient balance.

You placed your first borrow swap order. Keep track of its status in the [Monitor Swap Status](../../tools/swaps#monitor-swap-status) section.
