# Repay with Supply

Repay with supply combines withdraw, swap, and repay 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                                                                                                  |
| -------------------- | ------------------------------------------------------------------------------------------------------------ |
| **Avoid Liquidation**    | User wants to improve [Health Factor](../../positions#health-factor) by repaying debt using their supply        |
| **Rebalance Positions**  | User wants to consolidate stablecoin exposure by using idle supply to pay off debt in a different stablecoin |
| **Reduce Debt Exposure** | User wants to reduce debt load by converting non-collateral supply into debt repayment                       |

> [!WARNING]
> Repaying with supply lowers your supplied balance. If that asset is
> collateral, check that the position stays healthy.

Repay with supply can be broken down into the following steps:

1. Identify the supply position to use for repayment
2. Identify the borrow position to repay
3. Choose between market order and limit order
4. Execute the swap operation

## Identify the Supply Position to Repay With

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

```tsx title="UserSupplyItem"
const supplyPosition: UserSupplyItem = {
  id: "c3VwcGx5",
  reserve: {
    id: "SGVsbG8h",
    canSwapFrom: true,
    chain: {
      chainId: 1,
      name: "Ethereum",
    },
    spoke: {
      id: "aGVsbG8",
      // …
    },
    // …
  },
  isCollateral: true,
  balance: {
    amount: {
      value: BigDecimal(5000.0),
      exchange: {
        value: BigDecimal(5000.0),
        // …
      },
      // …
    },
    // …
  },
  principal: {
    amount: {
      value: BigDecimal(4800.0),
      // …
    },
    // …
  },
  interest: {
    amount: {
      value: BigDecimal(200.0),
      // …
    },
    // …
  },
  // …
};
```

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

## Identify the Borrow Position to Repay

Identify the borrow position among the user’s [borrow positions](../fetch#fetching-user-borrows) to repay.

```tsx title="UserBorrowItem"
const borrowPosition: UserBorrowItem = {
  id: "Ym9ycm93",
  reserve: {
    id: "V29ybGQh",
    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]
> The supply and borrow positions must be on the **same spoke**. The supply
> position’s asset is swapped to repay the debt.

## 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: RepayWithSupplyQuoteRequest = {
  market: {
    debtPosition: borrowPosition.id,
    repayWithReserve: supplyPosition.reserve.id,
    amount: bigDecimal(1000),
    user: evmAddress("0x123…"),
    // kind: RepayWithSupplyKind.Repay, // Optional: specify repay or supply priority
    // selectedSlippage: bigDecimal(1), // Optional: override suggested slippage
  },
};
```

```jsonc title="GraphQL Variables"
{
  "request": {
    "market": {
      "debtPosition": "Ym9ycm93",
      "repayWithReserve": "SGVsbG8h",
      "amount": "1000",
      "user": "0x123…",
      "kind": "REPAY" // Optional: "REPAY" or "SUPPLY"
    }
  }
}
```

The request takes the following parameters:

- `debtPosition`: The borrow position with debt to repay
- `repayWithReserve`: The reserve of the supply position to use for repayment
- `amount`: The swap amount, interpreted based on `kind`
- `user`: The user’s address
- `kind`: Repay (default) or Supply, determines how `amount` is interpreted
- `selectedSlippage`: Optional slippage tolerance to use instead of the suggested slippage

Since only one amount is provided, the `kind` parameter determines how it’s interpreted:

| Kind            | User inputs…                 | System calculates…                  |
| --------------- | ---------------------------- | ----------------------------------- |
| **Repay (default)** | The debt amount to _repay_ | The supply amount needed            |
| **Supply**          | The supply amount to _use_ | The debt amount that will be repaid |

### Limit Orders

Limit orders execute when your price condition is met.

```ts title="TypeScript"
const request: RepayWithSupplyQuoteRequest = {
  limit: {
    repayPosition: borrowPosition.id,
    repayAmount: bigDecimal(1000),
    supplyPosition: supplyPosition.id,
    supplyAmount: bigDecimal(1050), // Amount of supply to use
    user: evmAddress("0x123…"),
    kind: RepayWithSupplyKind.Repay,
    // deadline: new Date(Date.now() + 24 * 60 * 60 * 1000), // Optional: custom expiry
  },
};
```

```json title="GraphQL Variables"
{
  "request": {
    "limit": {
      "repayPosition": "Ym9ycm93",
      "repayAmount": "1000",
      "supplyPosition": "c3VwcGx5",
      "supplyAmount": "1050",
      "user": "0x123…",
      "kind": "REPAY"
    }
  }
}
```

The request takes the following parameters:

- `repayPosition`: The borrow position with debt to repay
- `repayAmount`: The amount of debt to repay
- `supplyPosition`: The supply position to use for repayment
- `supplyAmount`: The amount of supply to use
- `user`: The user’s address
- `kind`: Repay (default) or Supply, 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                                                      |
| ------ | ---------------------------------------------------------- | -------------------------------------------------------------------------------- |
| **Repay**  | The exact _repay_ amount and a maximum _supply_ usage  | Order fulfilled when supply price allows full debt repayment within supply limit |
| **Supply** | The exact _supply_ to use and a minimum _repay_ amount | Order fulfilled when enough debt can be repaid using the specified supply amount |

## Step-by-Step with AaveKit

To execute a repay with supply swap with AaveKit, follow these steps.

### 1. Get a Quote

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

<tabgroup>
<tab label="React">

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

function SwapQuote({ request }: { request: RepayWithSupplyQuoteRequest }) {
  const { data, loading, error } = useRepayWithSupplyQuote(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>
      Repay 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 RepayWithSupplyQuoteRequest,
  useRepayWithSupplyQuote,
} from "@aave/react";

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

  // data: SwapQuote
  return (
    <div>
      Repay 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 RepayWithSupplyQuoteRequest,
  useRepayWithSupplyQuoteAction,
} from "@aave/react";

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

const handler = async (request: RepayWithSupplyQuoteRequest) => {
  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 { repayWithSupplyQuote } from "@aave/client/actions";

import { client } from "./client";

// …

const result = await repayWithSupplyQuote(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: RepayWithSupplyQuoteRequest!, $currency: Currency!) {
  repayWithSupplyQuote(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="useRepayWithSupplyQuote"
import { Currency } from "@aave/react";

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

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

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

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

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

// …

const result = await repayWithSupplyQuote(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: {
      repayWithSupply: {
        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: {
      repayWithSupply: {
        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: {
      repayWithSupply: {
        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 repayWithSupplyQuote(client, request).andThen(
  ({ approvals, quote }) =>
    preview(client, {
      action: {
        repayWithSupply: {
          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 `repayWithSupply.fromQuote` field:

<tabgroup>
<tab label="GraphQL">

```json title="Variables"
{
  "request": {
    "action": {
      "repayWithSupply": {
        "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 `useRepayWithSupplyOrder` 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 { useRepayWithSupplyOrder } from "@aave/react";

const [repayWithSupply, { loading, error }] = useRepayWithSupplyOrder((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 { useRepayWithSupplyOrder } from "@aave/react";

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

const [repayWithSupply, { loading, error }] = useRepayWithSupplyOrder((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 { useRepayWithSupplyOrder } from "@aave/react";

const [repayWithSupply, { loading, error }] = useRepayWithSupplyOrder((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 repayWithSupplyQuote(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 repayWithSupply({
    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, repayWithSupplyQuote } 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 repayWithSupplyQuote(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 repay with supply order. Keep track of its status in the [Monitor Swap Status](../../tools/swaps#monitor-swap-status) section.
