# 收取费用和奖励

收取你 CLMM 仓位中已累积的交易手续费和 farm 奖励发放。

***

### CLMM 中手续费的工作方式

与手续费累积在池 vault 中并提升 LP 代币价值的 CPMM 池不同，CLMM 池按 **每个仓位**跟踪手续费。每个仓位会根据以下因素计入其应得的交易手续费份额：

* 该仓位在当前有效 tick 区间内的流动性份额。
* 经过该仓位价格区间的代币交换量。

手续费与流动性是分开收取的——你无需移除流动性即可领取手续费。

***

### 收取手续费和奖励

使用 `raydium.clmm.harvestAllRewards()` 来收取你所有仓位中待领取的交易手续费和奖励发放。

```typescript
import {
  ApiV3PoolInfoConcentratedItem,
  CLMM_PROGRAM_ID,
  DEVNET_PROGRAM_ID,
  ClmmPositionLayout,
} from '@raydium-io/raydium-sdk-v2'
import { initSdk, txVersion } from '../config'

const harvestAllRewards = async () => {
  const raydium = await initSdk()

  const allPosition = await raydium.clmm.getOwnerPositionInfo({
    programId: CLMM_PROGRAM_ID, // devnet: DEVNET_PROGRAM_ID.CLMM_PROGRAM_ID
  })
  const nonZeroPosition = allPosition.filter((p) => !p.liquidity.isZero())
  if (!nonZeroPosition.length)
    throw new Error(
      `user do not have any non zero positions, total positions: ${allPosition.length}`
    )

  const positionPoolInfoList = (await raydium.api.fetchPoolById({
    ids: nonZeroPosition.map((p) => p.poolId.toBase58()).join(','),
  })) as ApiV3PoolInfoConcentratedItem[]

  const allPositions = nonZeroPosition.reduce(
    (acc, cur) => ({
      ...acc,
      [cur.poolId.toBase58()]: acc[cur.poolId.toBase58()]
        ? acc[cur.poolId.toBase58()].concat(cur)
        : [cur],
    }),
    {} as Record<string, ClmmPositionLayout[]>
  )

  const { execute } = await raydium.clmm.harvestAllRewards({
    allPoolInfo: positionPoolInfoList.reduce(
      (acc, cur) => ({
        ...acc,
        [cur.id]: cur,
      }),
      {}
    ),
    allPositions,
    ownerInfo: {
      useSOLBalance: true,
    },
    programId: CLMM_PROGRAM_ID, // devnet: DEVNET_PROGRAM_ID.CLMM_PROGRAM_ID
    txVersion,
    // 可选：在此设置优先手续费
    // computeBudgetConfig: {
    //   units: 600000,
    //   microLamports: 46591500,
    // },
  })

  const { txIds } = await execute({ sequentially: true })
  console.log('harvested all clmm rewards:', { txIds })
}

harvestAllRewards()
```

#### 收取参数

| 参数             | 类型        | 描述                                           |
| -------------- | --------- | -------------------------------------------- |
| `allPoolInfo`  | object    | 包含所有有仓位池的 pool ID 到池信息的映射。                   |
| `allPositions` | object    | 某个池的 pool ID 到该池中仓位数组的映射。                    |
| `ownerInfo`    | object    | `{ useSOLBalance: true }` 接收原生 SOL 而不是 wSOL。 |
| `programId`    | PublicKey | CLMM 程序 ID。                                  |
| `txVersion`    | TxVersion | 交易版本。                                        |

{% hint style="info" %}
如果你在多个池中有仓位， `harvestAllRewards` 可能会生成多笔交易。使用 `execute({ sequentially: true })` 按顺序发送它们。
{% endhint %}
