# Partner attribution

Lighter's [Partner Attribution](https://apidocs.lighter.xyz/docs/partner-integration) program lets platforms earn fees on the trades they route. A **partner** is the integrator building on Lighter; a **client** is the partner's user, whose transactions the partner submits on their behalf. Once a client approves your partner account, every order you submit for them can carry an integrator fee that accrues to your account automatically.

The program is permissionless: any `account_index` can collect fees — including [sub-accounts](/docs/recipes/lighter/subaccounts) — so an account owned by an Openfort backend wallet works as the fee destination without anything extra.

## How it works

1. Your platform has a partner account on Lighter — its `account_index` is where fees accrue
2. The client approves your partner account with an `ApproveIntegrator` transaction, capping the maximum fees you may charge
3. Orders you submit for the client include the integrator fields (`IntegratorAccountIndex` plus maker/taker fee values)
4. Fees credit to your partner account when trades execute — in USDC for perpetual markets, in the received asset for spot markets

## Approve a partner (`ApproveIntegrator`)

The client authorizes your partner account with an `ApproveIntegrator` transaction that sets per-market-type fee caps and an expiry:

| Field | Meaning |
|-------|---------|
| `integrator_account_index` | Your partner account — all fees collected from the client's trades credit here |
| `max_perps_taker_fee` / `max_perps_maker_fee` | Maximum fees you may charge on perp orders |
| `max_spot_taker_fee` / `max_spot_maker_fee` | Maximum fees you may charge on spot orders |
| `approval_expiry` | Unix timestamp in milliseconds when the approval lapses (max `2^48 − 1`) |

Two constraints Lighter enforces at the protocol level:

* **At most 4 approved partners per client** at any point in time.
* **Global maximum fee limits** — an approval exceeding them fails outright.

The signature requirement depends on whose account is being approved: an L1 signature is required when the approved `account_index` belongs to a different L1 address; only an L2 (API key) signature is needed when it shares the same L1 address or all fees are zero. There's no TypeScript SDK for this transaction — Lighter's official Python SDK exposes it as `client.approve_integrator(...)`, and `lighter-go` carries the corresponding transaction type.

## Attach fees to orders

`SignCreateOrder` takes the integrator fields on every order. This recipe's TypeScript wrapper ([`server/signer/signer.ts`](https://github.com/openfort-xyz/recipes-hub/blob/main/lighter/server/signer/signer.ts)) pins them to zero, since the demo charges no fees:

```ts
const NIL_INTEGRATOR_INDEX = 0;
const NIL_INTEGRATOR_FEE = 0;

wasmGlobals().SignCreateOrder(
  // ...order params...
  params.orderExpiry,
  NIL_INTEGRATOR_INDEX, // your partner account_index goes here
  NIL_INTEGRATOR_FEE, // maker/taker fee values
  NIL_INTEGRATOR_FEE,
  // ...
)
```

To collect fees, extend the wrapper to accept real values instead of the nil constants and pass your partner `account_index` plus fee values on each order. The fees on an order **must not exceed the maximums the client approved** in the `ApproveIntegrator` step.

## Fee values

Fee values are expressed in parts-per-million of trade size:

```text
fee = trade_size × (fee_value / 1_000_000)
```

A fee value of `1000` is 10 basis points (0.10%); `500` is 5 bps. Perp fees are paid and credited in USDC; spot fees are paid and credited in the received asset.

## Revoke a partner

There is no separate revoke transaction: the client submits another `ApproveIntegrator` for the same partner with **all fees set to zero**. Since zero-fee approvals only need an L2 signature, revocation doesn't require a fresh `personal_sign` from the client's Openfort wallet.

## Best practices

* **Set approval caps above your actual fee** — this leaves room to adjust per-order fees without asking clients to re-approve.
* **Track `approval_expiry`** — an expired approval silently stops fee collection; re-approve before it lapses rather than after orders start failing your expectations.
* **Use a dedicated account for fee collection** — a sub-account or separate Openfort-owned account keeps fee revenue segregated from any trading the platform does itself.
* **Verify against Lighter's current global fee limits before launch** — the caps are protocol-enforced and an approval above them fails.
