Surface Map
Concepts
TraderCode. Every wallet has a default code derived from its address, displayed by clients asMonaco - <address>. Codes are globally unique, work across every app on Monaco, and the default is permanent. Calling getMyTraderCode is idempotent — the code row is created on demand, so the endpoint never 404s for a signed-in wallet. Render the response’s display field rather than building the display string yourself; it already reflects a custom handle when one is set.
Custom handle. A wallet can claim a custom (vanity) handle to use in place of the wallet-derived default: letter-first, [A-Za-z0-9_], 5–20 characters, stored exactly as entered (casing preserved) but unique case-insensitively. Claim or edit it with setTraderCode, drop it with clearTraderCode (reverting to the default), and preview a handle with the public checkTraderCodeAvailability. getMyTraderCode reports isCustom and the claimed customCode alongside the default code. The referral chain always keys on the wallet, so changing or clearing a handle never affects earned rewards or referral relationships.
Referral chain. A referral relationship is recorded once at first signup. The chain is a directed graph: L1 is the direct referrer, L2 is their referrer, L3 is L2’s referrer. Each level earns a configured percentage of the net fee generated by the referred user’s trades.
Reading referral state. Two self-scoped, authenticated reads back the referral UI. getMyReferralPosition() returns your direct (L1) referrer (referrer is "" when you were not referred), your all-time totalEarned, and recent reward rows (up to the 100 newest; totalEarned stays the complete aggregate) — use it for an “already referred” state and an earnings header. getMyReferralDownline() returns earningsBySource (who pays you, across L1/L2/L3), your L1 directReferees roster (including referees who have not traded yet, showing up to the 500 most recent effective referees (after per-wallet dedupe), drawn from a bounded scan so a very large history may yield an incomplete roster — the earnings views stay unbounded), and a per-level summary. Both identify every other user by wallet address plus a display (their custom handle when claimed), never an internal id, and only ever return your own chain.
Rewards bucket. Earned rewards land in a dedicated per-user rewards bucket that is separate from any application’s trading balance. The bucket is app-agnostic — a referrer earns rewards regardless of which app their referee trades on. To spend rewards, move them into a trading balance via transferRewards.
Transfer. The transfer between rewards bucket and trading balance is ledger-only (Monaco operates a single shared vault). No on-chain transaction, no gas. Funds are tradeable immediately after the transfer.
Flow
1. Capture a referral at signup
Pass the referral code in the auth verify body. The code is silently ignored if it is invalid or if the user already exists, so it never blocks sign-in. The trading front-end captures?ref=CODE from the URL and forwards it here.
1
Validate the code (optional)
Before showing the user a confirmation, call the public lookup to verify the code resolves.Returns
404 when the code does not resolve to a known wallet.2
Pass the code on verify
Include For returning users the field is ignored. Self-referrals are silently dropped.
referralCode in the auth verify request.2. Get and display a user’s TraderCode
Fetch the authenticated user’s code to display it in the UI as a shareable link or copyable string.customCode holds it (as entered), isCustom is true, and display is the handle.
3. Claim a custom handle (optional)
Let a user replace the wallet-derived default with a vanity handle. Preview availability as they type with the public check, then claim it. The handle is stored exactly as entered, must be letter-first[A-Za-z0-9_] and 5–20 characters, and is unique case-insensitively.
setTraderCode maps rejections to 409 (handle already taken, or a recently-freed handle still in cooldown), 422 (validation, with a reason code), 429 (edited too frequently), and 403 (custom handles are disabled). clearTraderCode counts against the same rolling-hour edit limit, so it can also return 429 or 403. The public availability check is rate-limited and returns 429 once a caller exceeds the allowance — treat it as advisory feedback, not the authoritative gate.
4. Check rewards balance
Read accumulated rewards across all reward tokens. Returns an empty list if no rewards have been earned yet.available is in raw atomic units. Divide by the token’s decimals (e.g., 10^6 for USDC) to display a human-readable amount.
5. Transfer rewards to a trading balance
Move earned rewards from the rewards bucket into the authenticated application’s trading balance. The transfer is instant and ledger-only — no on-chain transaction.409 when the requested amount exceeds the available rewards balance.
Reward Rates
Reward rates are configured by Monaco and may change over time. Current testnet defaults:
Rewards are computed on the net fee (taker fee minus maker rebate) at fill time and credited instantly to the referrer’s rewards bucket. Missing levels — where the chain is shorter than 3 — are simply not paid.
Builder Checklist
- Capture
?ref=CODEfrom the URL before the user completes sign-in, and pass it assdk.auth.authenticate(clientId, code)or via the raw auth verify endpoint —sdk.logindoes not forward a referral code. - Validate the code with
getTraderCodeInfobefore showing a confirmation to the user; return a clean message on404instead of an error. - Never block sign-in on referral-code validation failures — a bad code is silently ignored server-side, but front-end validation errors should not prevent login.
- Render the
displayfield fromgetMyTraderCoderather than composing the display string yourself, and readisCustomto reflect whether a vanity handle is set. - In a custom-handle claim form, debounce
checkTraderCodeAvailabilityfor live feedback, but always handle409/422/429onsetTraderCode— the server is the authoritative gate, not the advisory check. - Display
availablereward balances in human-readable form by dividing by the token’s decimal precision. - Handle
409ontransferRewardsby refreshing the balance and showing the user their current available amount.
Related References
- Earn for the product overview of TraderCodes and BuilderCodes
- Auth for the full sign-in flow
- TypeScript TraderCodes SDK for complete method signatures
- REST — Get your TraderCode for the generated schema
- REST — Look up a TraderCode for the generated schema
- REST — Get rewards balance for the generated schema
- REST — Transfer rewards for the generated schema

