Skip to main content
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.

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 newest-first per-trade credits for the authenticated application. page defaults to 1 and must be 1–10000; page_size defaults to 20 and must be 1–100; a value out of range is INVALID_ARGUMENT. 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 after the revenue-share clamp. 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 BuilderCodes is disabled, 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 UNAVAILABLEs 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.