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

# OTC trades with the SDK

> Settle a direct trade between two known counterparties from the SDK. A maker signs an AugustusRFQ order naming a specific taker, and that taker fills it on-chain.

**OTC** (over-the-counter) is a direct trade negotiated between two known counterparties rather than discovered through a public route. In the SDK it's a signed AugustusRFQ order, exposed under the `sdk.otcOrders` namespace: a **maker** signs the terms off-chain naming a specific **taker**, and only that taker can fill the order on-chain.

Mechanically it's a signed on-chain order whose defining field is the **`taker`**: you name the counterparty's address, and only that address can fill the order: a private, fillable-by-one OTC trade (`P2P`).

<Note>
  This is for **bilateral, counterparty-specific** trades. For open, target-price orders that any solver can fill, use [Limit orders](/sdk/products/limit-orders) (Delta) instead; those are gasless and MEV-protected. For the conceptual difference, see [Product stack → OTC](/overview/product-stack/otc).
</Note>

## When to use this

* The counterparty matters as much as the price: treasury rebalancing, partner deals, market-maker inventory moves.
* You've agreed terms off-book and want a verifiable on-chain settlement restricted to the agreed counterparty.
* You don't want the trade exposed as a public order before it settles.

## How it works

OTC has two sides. The **maker** builds and signs the order (gasless, off-chain). The **taker** (the named counterparty) submits the fill transaction on-chain through the AugustusRFQ contract.

<Steps>
  <Step title="Maker approves the maker asset">
    The maker approves AugustusRFQ to pull the asset they're selling: `sdk.otcOrders.approveMakerTokenForOTCOrder(makerAmount, makerAsset)`.
  </Step>

  <Step title="Maker signs and posts the order">
    The maker builds an order naming the intended `taker`, signs the EIP-712 typed data, and posts it: `sdk.otcOrders.submitOTCOrder({ ...terms, taker })`. Posting stays off-chain, so the maker pays nothing.
  </Step>

  <Step title="Taker approves the taker asset">
    The taker approves AugustusRFQ for the asset they're paying with: `sdk.otcOrders.approveTakerTokenForOTCOrder(takerAmount, takerAsset)`.
  </Step>

  <Step title="Taker fills on-chain">
    The taker submits the fill: `sdk.otcOrders.fillOTCOrder({ order, signature })`. AugustusRFQ verifies the signature and the named taker, then settles the swap.
  </Step>
</Steps>

## Maker: build, sign, and post

```ts theme={null}
const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
const ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";

// 1. Approve the asset the maker is selling
await sdk.otcOrders.approveMakerTokenForOTCOrder(
  "10000000000", // 10,000 USDC
  USDC,
);

// 2. Build, sign, and post in one call; `taker` is what makes it OTC
const order = await sdk.otcOrders.submitOTCOrder({
  maker: account,
  taker: counterparty, // the intended counterparty; only this address can fill
  makerAsset: USDC,
  takerAsset: ETH,
  makerAmount: "10000000000", // maker gives 10,000 USDC
  takerAmount: "3000000000000000000", // maker wants 3 ETH
  expiry: Math.floor(Date.now() / 1000) + 60 * 60 * 24, // 24h
});

// `order` carries the signed terms + signature; hand it to the taker
// (API, your backend, or any off-chain channel)
```

To split the steps (e.g. to sign with a hardware wallet), use `sdk.otcOrders.buildOTCOrder` → `sdk.otcOrders.signOTCOrder` → `sdk.otcOrders.postOTCOrder`.

## Taker: fill the order

The taker receives the maker's signed order, approves the asset they're paying with, and fills on-chain:

```ts theme={null}
// 1. Approve the asset the taker is paying with (skip for native ETH)
await sdk.otcOrders.approveTakerTokenForOTCOrder(
  order.takerAmount,
  order.takerAsset,
);

// 2. Fill directly against AugustusRFQ
const tx = await sdk.otcOrders.fillOTCOrder({
  order, // the maker's order data
  signature: order.signature, // the maker's signature
});
```

The fill reverts if the order is expired, already filled, or the caller isn't the named taker, so always re-check `expiry` against the current block before submitting.

## Query and cancel

```ts theme={null}
// Maker: list your OTC orders
const mine = await sdk.otcOrders.getOTCOrders({ maker: account });

// Taker: list orders addressed to you
const forMe = await sdk.otcOrders.getOTCOrders({ taker: account });

// Maker: cancel an unfilled order on-chain
await sdk.otcOrders.cancelOTCOrder(orderHash);
```

Cancellation here is an on-chain call to AugustusRFQ, so it costs gas, unlike the gasless `cancelDeltaOrders` flow for Delta orders.

`sdk.otcOrders.getOTCOrdersContract()` returns the AugustusRFQ address for the active chain; see [Chains & contracts](/resources/chains-and-contracts) for all deployments.

## Related pages

* [Limit orders](/sdk/products/limit-orders): open, gasless target-price orders (Delta).
* [Product stack → OTC](/overview/product-stack/otc), the conceptual model.
* [API reference → AugustusRFQ](/api-reference/rfq/overview) — the underlying order surface.
* [Chains & contracts](/resources/chains-and-contracts) for AugustusRFQ deployment addresses.
