Fees API
Trading fees from a token’s Meteora pool accrue to the lock escrows that
hold the pool’s LP tokens (see Launch API → LP lock fields).
At launch Etch locks 100 % of the LP permanently: 90 % in an escrow owned by
the launch beneficiary, 10 % in an escrow owned by the Etch wallet
(platformFeeBps: 1000). Each escrow owner claims its own share; nobody can
withdraw the liquidity itself.
Claims are user-signed: Etch only builds the transaction, the escrow owner
signs and sends it (same flow as the Transactions API). The former
custodial GET /fees / POST /fees/:mint/claim routes were removed.
Get Fees
GET /api/fees/:mint
Auth: Etch JWT. Returns the fees accrued to the caller’s lock escrow on the token’s pool. A wallet that holds no escrow (a fan, or the creator of a legacy unlocked launch) gets zeros — not an error.
Response
{
"mint": "AWE1234...",
"wallet": "8vP2...",
"pool": "POOL5678...",
"lpLocked": true,
"platformFeeBps": 1000,
"claimable": { "tokenA": "123456789", "tokenB": "9876543" },
"claimed": { "tokenA": "0", "tokenB": "0" },
"escrow": "ESCROWc...",
"lockedLp": "900000000000"
}| Field | Description |
|---|---|
claimable.tokenA / tokenB | Fees the caller can claim now, in raw units (9 decimals). tokenA is the launched token, tokenB is SOL |
claimed.tokenA / tokenB | Fees already claimed from this escrow (raw units) |
lpLocked | Whether the launch locked its LP (legacy launches: false) |
escrow | The caller’s lock escrow account, or null when the wallet holds none |
lockedLp | LP amount locked in that escrow (raw) |
Values come from Meteora’s getUserLockEscrow(owner): the escrow’s unclaimed
LP fee is converted to token amounts at the pool’s current virtual price.
Errors
| Status | error | Meaning |
|---|---|---|
| 401 | unauthorized | Missing / invalid JWT |
| 404 | token_not_found | No launch for this mint |
| 500 | fees_unavailable | RPC / SDK error while reading the escrow |
Claim Fees
POST /api/fees/:mint/tx
Auth: Etch JWT. Builds an unsigned Meteora claimFee transaction for the
caller’s lock escrow. The caller is fee payer and escrow owner; Etch never
signs it.
Request Body
{ "action": "claim" }Response
The standard built transaction plus the escrow and the amounts being claimed:
{
"transaction": "<base64 legacy Transaction, unsigned>",
"version": "legacy",
"feePayer": "<wallet>",
"blockhash": "…",
"lastValidBlockHeight": 123,
"signers": ["<wallet>"],
"summary": "Claim AWE trading fees from lock escrow ESCR…c123",
"escrow": "ESCROWc...",
"claimable": { "tokenA": "123456789", "tokenB": "9876543" }
}Deserialize by version, sign with the wallet, sendRawTransaction, then
confirm with { signature, blockhash, lastValidBlockHeight } (or
POST /api/tx/confirm). The transaction creates the owner’s token accounts
for both pool tokens if needed and unwraps the SOL side.
Errors
| Status | error | Meaning |
|---|---|---|
| 401 | unauthorized | Missing / invalid JWT |
| 400 | invalid_request | action is not "claim" |
| 400 | no_fees | The escrow exists but nothing has accrued yet |
| 403 | no_escrow | The wallet holds no lock escrow for this pool (not the beneficiary, or a legacy unlocked launch) |
| 404 | pool_not_found | No launch / pool for this mint |
| 429 | rate_limit_exceeded | tx bucket (30 requests / minute) |
| 500 | build_failed | RPC / SDK error while building |