# Builder codes

Builder codes enable platforms to earn a portion of the trading fees generated by their users on Hyperliquid. When a user approves your builder code, a fee attaches to every order they place through your application.

## How builder codes work

1. Your platform has a builder address (an Openfort backend wallet)
2. Users approve your builder to collect fees from their trades
3. When you submit orders on behalf of users, include the builder fee
4. Hyperliquid routes the fee to your builder address

## Approve builder fees

Before collecting fees, the trading wallet must approve your builder address:

```ts
import Openfort from '@openfort/openfort-node'
import * as hl from '@nktkas/hyperliquid'

const openfort = new Openfort(process.env.OPENFORT_SECRET_KEY!, {
  walletSecret: process.env.OPENFORT_WALLET_SECRET!,
})

// Your platform's builder wallet
const builder = await openfort.accounts.evm.backend.create()

// User's trading wallet
const trader = await openfort.accounts.evm.backend.create()

const transport = new hl.HttpTransport({ isTestnet: true })
const traderExchange = new hl.ExchangeClient({ wallet: trader, transport })

// Trader approves builder to collect fees
await traderExchange.approveBuilderFee({
  builder: builder.address,
  maxFeeRate: '0.001', // 0.1% max fee rate
  nonce: Date.now(),
})
```

## Apply builder fee to orders

Include the builder fee when placing orders:

```ts
await traderExchange.order({
  orders: [
    {
      a: 4,
      b: true,
      p: '3000.0',
      s: '0.1',
      r: false,
      t: { limit: { tif: 'Gtc' } },
    },
  ],
  grouping: 'na',
  builder: {
    b: builder.address,
    f: '0.0005', // 0.05% fee rate
  },
})
```

:::tip
Set the `maxFeeRate` in `approveBuilderFee` higher than your actual fee rate. This gives you room to adjust fees without requiring users to re-approve. The actual fee charged per order is specified in the `builder.f` field.
:::

## Check approval status

Verify whether a user has approved your builder:

```ts
const info = new hl.InfoClient({ transport })

const builderApprovals = await info.maxBuilderFee({
  user: trader.address,
  builder: builder.address,
})

console.log('Approved:', builderApprovals)
```

## Fee structure

| Parameter | Description |
|-----------|-------------|
| `maxFeeRate` | Maximum fee the builder can charge (set by trader) |
| `builder.f` | Actual fee rate applied per order (set by builder) |
| Fee basis | Applied to the notional value of each trade |

:::warning
The fee rate in `builder.f` must be less than or equal to the `maxFeeRate` the trader approved. The exchange rejects orders with a higher fee rate.
:::

## Best practices

* **Set `maxFeeRate` higher than your actual fee** — this gives room to adjust fees without requiring users to re-approve
* **Keep fees competitive** — perps max 0.10% (10 bps), spot max 1.00% (100 bps); lower fees attract more volume
* **Test on testnet first** — verify the full approval and fee flow before going live
* **Monitor builder fee revenue** — track fill rates and fee collection to optimize your fee structure over time
