> ## Documentation Index
> Fetch the complete documentation index at: https://docs.0xmonaco.com/llms.txt
> Use this file to discover all available pages before exploring further.

# BuildercodeRewardsService

> BuilderCodes frontend revenue-share earnings and payout claim

Package: `monaco.api.buildercodes`

Source: `protos/api/buildercodes.proto`

Use `BuildercodeRewardsService` to inspect a frontend's BuilderCodes program,
earnings, and reserved balances, then claim accrued revenue share into a
tradeable balance.

```protobuf theme={null}
service BuildercodeRewardsService {
  rpc GetBuildercodesConfig(GetBuildercodesConfigRequest) returns (GetBuildercodesConfigResponse);
  rpc SetBuilderFee(SetBuilderFeeRequest) returns (SetBuilderFeeResponse);
  rpc ListBuilderFeeChanges(ListBuilderFeeChangesRequest) returns (ListBuilderFeeChangesResponse);
  rpc ListBuildercodePayouts(ListBuildercodePayoutsRequest) returns (ListBuildercodePayoutsResponse);
  rpc GetBuildercodePayoutSummary(GetBuildercodePayoutSummaryRequest) returns (GetBuildercodePayoutSummaryResponse);
  rpc GetBuildercodeRewardsBalance(GetBuildercodeRewardsBalanceRequest) returns (GetBuildercodeRewardsBalanceResponse);
  rpc ClaimBuildercodeRewards(ClaimBuildercodeRewardsRequest) returns (ClaimBuildercodeRewardsResponse);
}
```

## Notes

* BuilderCodes provides per-trade frontend payouts. An enrolled frontend can earn Monaco revenue share and can charge its own builder fee. Every positive builder fee charged to a taker is credited in full to the enrolled application's claimable payout balance with kind `BUILDER_FEE`; revenue-share credits use `REVENUE_SHARE`. A claim moves the reserved payout balance into a spendable trading balance.
* Every RPC requires authentication and rejects delegated sessions. No program switch gates reads or claims; `SetBuilderFee` needs the revenue share or builder fees switched on. `GetBuildercodesConfig`, `SetBuilderFee`, `ListBuilderFeeChanges`, `ListBuildercodePayouts`, and `GetBuildercodePayoutSummary` derive the application from the session and require the authenticated wallet to match its configured payout address; callers cannot select an application or payout wallet.
* `GetBuildercodesConfig` returns the authenticated application's UUID, enrollment and payout-address state, the live BuilderCodes enabled/budget values, and `builder_fee_enabled`, stored `builder_fee_bps`, effective `builder_fee_cap_bps`, `changes_remaining`, and `next_change_allowed_at`. The effective cap never exceeds 100 bps. `buildercodes_enabled` reports whether the revenue share is on; reads succeed either way.
* `SetBuilderFee` accepts an integer from 0 through 100; a real change must also be at or below `builder_fee_cap_bps`. The application must be enrolled with a payout address. At most two `BUILDER` changes are allowed in a rolling 24 hours; `ADMIN` changes do not count. Setting the current value succeeds without using a change, even when none remain or the live cap has fallen below that value. The fee may be set while `builder_fee_enabled` is false as long as the revenue share is on, and is refused while both are off.
* `SetBuilderFee` requires an explicit `bps` (`0` clears the fee). It returns `INVALID_ARGUMENT` for a missing value or a real change above the cap, `FAILED_PRECONDITION` when enrollment is incomplete after ownership passes or the rolling change limit is exhausted, `PERMISSION_DENIED` when both fee switches are off or the non-delegated frontend payout-wallet gate fails (including a missing payout address), `NOT_FOUND` when the session application is absent, `UNAUTHENTICATED` without valid authentication, and `INTERNAL` on a backend failure. Maintenance may return `UNAVAILABLE` before the write. A change-limit message includes the next allowed RFC 3339 time. Setting the stored value remains a no-op even if the live cap has fallen below it; a newly stored fee reaches order requests within seconds. Sequencer ordering is authoritative for the builder-fee gate and enrollment: an order processed before one of those sequenced changes uses the earlier state, and a later order uses the new state. Builder fees are charged on taker fills only, so a resting remainder that later fills as maker pays none. Server keys are not accepted.
* `ListBuilderFeeChanges` returns `BUILDER` and `ADMIN` changes newest first. `page_size` defaults to 20 and must be from 1 through 100; continue with the opaque `next_page_token`. `actor` is the payout wallet for a `BUILDER` row and the operator email for an `ADMIN` row.
* `ListBuilderFeeChanges` returns `INVALID_ARGUMENT` for an invalid page size or token; the shared authenticated-read errors below also apply. An empty `next_page_token` ends the walk.
* `ListBuildercodePayouts` returns per-trade credits for the authenticated application, newest first across persistor batches. It is cursor-paginated: send an empty `page_token` to start, then each response's `next_page_token` until it comes back empty; an empty token is definitive. `page_size` defaults to `20` and must be 1–1000; a value out of range is `INVALID_ARGUMENT`. There is no `page` field: a stub generated from an older proto that still sets it has the unknown field discarded and reads the first page on every call, so regenerate it. The token is pinned to the request's `kind` filter; a token reused with a different filter is `INVALID_ARGUMENT`. The walk orders on `(created_at, id)` descending, which never skips or repeats a credit but is not chronological inside one persistor batch: every credit a batch writes shares its `created_at`, and the `id` tie-break is random. Each row exposes the trade, payout address at credit time, token, RAW atomic-unit amount, applied basis points, RFC 3339 timestamp, and `kind`. For `BUILDER_FEE`, the applied rate is the normalized builder-fee rate charged to the taker. For `REVENUE_SHARE`, it is the realized rate for that fill and may be lower than the configured budget. The optional `kind` request field lists one kind only, and `total`/`total_pages` then count that kind; any other value is `INVALID_ARGUMENT`. Pagination counts are JSON numbers.
* `GetBuildercodesConfig`, `ListBuilderFeeChanges`, `ListBuildercodePayouts`, and `GetBuildercodePayoutSummary` return `PERMISSION_DENIED` when the session is delegated or the authenticated wallet is not the application's configured payout address, `NOT_FOUND` when the authenticated application cannot be found, `UNAUTHENTICATED` without a session, `RESOURCE_EXHAUSTED` when the account's read budget is exhausted and enforced (retry after `RetryInfo`), and `INTERNAL` on a backend read failure.
* `GetBuildercodePayoutSummary` returns a total credit count plus totals separated by token; RAW atomic-unit amounts from different tokens are never combined. `by_token` sums both payout kinds; `by_token_and_kind` splits the same totals by token and `kind`, and a token's rows add up to its `by_token` total. `last_credited_at` is absent/null and both lists are empty when no payouts exist.
* `GetBuildercodeRewardsBalance` derives the reserved reward bucket from the authenticated wallet, not the application payout address. It returns one entry per token with non-zero available RAW atomic-unit balance, or an empty list. Current enrollment is deliberately not required, so a former payout wallet can inspect and claim previously accrued funds.
* `ClaimBuildercodeRewards` requires authentication and moves the specified amount from the caller's payout bucket into the calling application's trading balance. The move is ledger-only — no on-chain transaction and no gas — and the credited funds are immediately tradeable. Taking the money off the exchange then follows the ordinary withdrawal flow.
* The payout bucket is resolved from the authenticated caller's own wallet address and never from the request, which carries only `token` and `amount`. A caller can therefore only claim their own accrued balance.
* Returns `FAILED_PRECONDITION` when the payout balance is insufficient for the requested amount, including when the wallet has never accrued a share — an empty bucket and a bucket that never existed report the same thing, because in both cases there is no balance to move.
* Returns `RESOURCE_EXHAUSTED` with a `RetryInfo` detail when the per-user movement budget the claim shares with withdrawals and collateral transfers is enforced and spent. It is refused before the claim reaches the sequencer, so nothing committed and it is safe to retry after the interval.
* Returns `PERMISSION_DENIED` when the session is a delegated agent. A delegated grant conveys only order-management authority, and this claim turns reserved balance into a tradeable one. No program switch gates the claim: a balance already credited stays claimable whether or not the revenue share is on.
* Returns `UNAVAILABLE` when the matching engine is unreachable, restarting, or slow to answer. Treat it as an **unknown** outcome rather than a rejection: the request is admitted to the sequencer before its reply is sent, so a claim that timed out in transit may still commit, and there is no idempotency key to make a retry safe. Do **not** retry automatically, and do not settle it with a balance read: an admitted claim can still be queued when the balance is read, so an unchanged balance does not prove the claim will not commit. Treat the claim as pending, re-check once the engine is healthy, and reconcile before issuing another.
* Two `UNAVAILABLE`s are **not** ambiguous, and both are tagged. A deliberate maintenance block is refused before the handler runs (`x-maintenance-blocked: true` metadata; REST `"error": "OPERATIONS_BLOCKED"`), and a sequencer admission rejection is refused before the command is queued (`OVERLOADED` in the status' error details; REST `"code": "OVERLOADED"`). Neither reached the sequencer, so both committed nothing and are safe to retry with backoff — an overload positively wants one. Only an untagged availability failure carries the unknown outcome.
* The payout wallet may be an **EOA or a smart-contract wallet**. An EOA answers Monaco's signature challenge directly; a multisig such as a Safe holds no private key and instead authenticates by **EIP-1271** contract signature, where Monaco asks the wallet contract whether it accepts the challenge. That path is narrow by design and is offered only to a wallet holding a BuilderCodes payout bucket, only while `contract_wallet_auth_enabled` is on, and only where the deployment has a chain RPC endpoint configured. While any of those is unmet, login is EOA-only and a contract payout wallet can call neither this endpoint nor the withdrawal flow that follows, leaving its accrued share unclaimable. Because a multisig collects owner approvals before it can answer, challenges stay valid for 30 minutes rather than the usual 5 whenever `contract_wallet_auth_enabled` is on — for **every** address, not only eligible ones, so the unauthenticated challenge response cannot be used to probe which addresses hold a payout bucket.
* Current enrollment is deliberately **not** required. Payout-address changes are not retroactive — future shares accrue to the new wallet while everything already accrued stays with the old one — so the previous wallet can still claim what it earned while it was the payout address. Requiring present-day enrollment would leave that balance unclaimable by anyone.
* `amount` is in RAW atomic units of `token`, and BuilderCodes shares accrue in the quote token of the traded pair.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.