> For the complete documentation index, see [llms.txt](https://docs.turbine.exchange/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.turbine.exchange/trading/trade-programmatically.md).

# Trade Programmatically

To trade on Turbine you:

1. Authenticate
2. Submit an order intent
3. Wait for Turbine to execute a trade

{% hint style="success" %}
The easiest way to interact with Turbine programmatically is the [Typescript SDK](https://github.com/propeller-heads/turbine-sdk).

We will use it throughout this guide.
{% endhint %}

{% hint style="info" %}
See the [`submit-orders.ts`](https://github.com/propeller-heads/turbine-sdk/blob/main/scripts/submit-orders.ts) script in the SDK repo for a complete example of submitting orders.
{% endhint %}

{% stepper %}
{% step %}
**Prepare your wallet**

To submit an order intent to Turbine and have it executed, the following conditions must be met:

* You need to have enough balance of sell token.
* You need to approve [Permit2 contract](https://etherscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3) to spend at least the amount you're selling (i.e. call `approve(permit2address, amount)` on the sell token contract).
  {% endstep %}

{% step %}
**Instantiate TurbineClient**

Fill the below example with the following values:

* `PRIVATE_KEY` - private key of the wallet
* `RPC_URL` - URL to access Ethereum blockchain; you can use your private RPC or pick one from <https://ethereumnodes.com/>
* `TURBINE_API_URL` - URL of Turbine API instance, with `/api` suffix. E.g. `https://api.turbine.exchange/api`.

```typescript
import { createPublicClient, createWalletClient, http, Hex } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { TurbineClient, OrderIntent, getRandomSalt, spreads } from "turbine-sdk";

const account = privateKeyToAccount(PRIVATE_KEY);
const walletClient = createWalletClient({
    account: account,
    chain: mainnet,
    transport: http(RPC_URL),
});
const publicClient = createPublicClient({
    chain: mainnet,
    transport: http(RPC_URL),
});

const turbineClient = await TurbineClient.create(
    walletClient,
    publicClient,
    TURBINE_API_URL
);
```

{% endstep %}

{% step %}
**Authenticate**

To submit orders you must be authenticated. See [Authentication](/reference/api/authentication.md) for details.

The SDK handles authentication automatically.
{% endstep %}

{% step %}
**Create an order intent**

Create an order to sell 30 USDC for WETH.

Sell at most 1% below the market price, with a floor of 0.007 WETH for those 30 USDC (\~0.00023 WETH per USDC).

{% hint style="info" %}
In Turbine, all orders are sell orders, so the higher the price, the better.
{% endhint %}

```typescript
const now = BigInt(Math.floor(Date.now() / 1000));
const orderIntent: OrderIntent = {
    owner: account.address,
    sellToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
    buyToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH
    sellAmount: 30n * 10n ** 6n, // 30 USDC in atomic units
    minBuyAmount: 7n * 10n ** 15n, // 0.007 WETH in atomic units
    spreadCurve: spreads.constant(100), // 1%
    startTime: now,
    endTime: now + 300n, // 300 seconds = 5 minutes
    partialFill: true, // only partially fillable orders are supported
    callData: "0x",
    callDataTarget: "0x0000000000000000000000000000000000000000",
    salt: getRandomSalt(),
};
```

{% endstep %}

{% step %}
**Submit order intent**

Submit the intent to Turbine:

```typescript
const orderHash = await turbineClient.addOrder(orderIntent);
```

This call errors if Turbine rejects your order during initial validation.

Submitting the intent does not execute it. Your order must still pass [the speedbump](/features/the-speedbump.md) and then get matched.

{% hint style="info" %}
This method calls: [Turbine](/reference/api/readme/turbine.md#post-api-add_order)
{% endhint %}
{% endstep %}

{% step %}
**Check order state**

To check order state, call `getOrderStates`:

```typescript
const orderState = (await turbineClient.getOrderStates([orderHash]))[0];
console.log(orderState.status);
```

The order can be in the following states:

* `Active` - The order is in the orderbook.
* `Invalid` - The order was removed due to validation errors during a settlement.
* `Expired` - The order was removed because it expired.
* `Filled` - The order was fully filled and removed from the orderbook.
* `PendingCancellation` - The owner has requested cancellation.
* `Canceled` - The owner canceled the order.

{% hint style="info" %}
This method calls: [Turbine](/reference/api/readme/turbine.md#post-api-order_states)
{% endhint %}
{% endstep %}
{% endstepper %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.turbine.exchange/trading/trade-programmatically.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
