On-chain architecture: one wallet per job
Every coin launches on pump.fun's bonding curve (the only rail since 2026-10-28), quoted in SPCX, with a creator fee the dev sets, and the money around it is kept apart by what it is for: each wallet does one job, and the thing it cannot do is what matters. The Meteora dynamic-bonding-curve rail and the Orca Whirlpool rail are closed for new launches (the gateway offers them only if an operator sets GROKPAD_LAUNCH_VENUES; the default is pumpfun); the coins already on them keep trading, the keeper collects and pays their fees as before, and the parts of this page about those rails describe that. Server signing is off in production until the keys below are set (see "Switching it on"); launches stay closed until then.
The wallets
| GrokPad wallet | Job | Custody |
|---|---|---|
| Creator | The dev's own wallet. Signs and pays for the launch; frozen into the coin's metadata as the wallet the dev share is paid to | the dev |
| Agent (one per coin) | Created by the gateway at launch. Receives 80% of the coin's creator fees, in SPCX, and the dev's first buy; buys its desk's calls once the dev arms it, with the SOL the dev deposits. Withdrawals go only to the dev: the deposit any time, earnings after 72h at most 5% of the balance per 24h, the SPCX with kind: "quote" | hot, sealed per coin by the gateway |
| Keeper (the treasury, "pad") | Holds the right to every coin's fees: the only share of a pump.fun coin's fee-sharing config; for the coins from the closed rails, the Meteora partner config's fee claim and the graduated pool's locked position, or an Orca coin's Whirlpool position (locked liquidity it can never withdraw, nor can anyone; on pump.fun GrokPad holds no liquidity at all). Collects every few minutes, pays the agent's share, keeps GrokPad's, sweeps it to ops above a gas reserve. Signs its part of a launch where there is one (none on pump.fun) and finished Orca launches cut short | hot, gateway (GROKPAD_TREASURY_SECRET) |
| Ops | Inference bills and the team. Receives the keeper's sweeps | cold; the server never holds its key |
Fees and the split
Every trade pays the venue's fee. On pump.fun (every coin launched since 2026-10-28) pump.fun keeps its own trade fee and routes the coin's creator fee, through the coin's fee-sharing config, to the keeper, on the curve and in the PumpSwap pool the coin graduates into. On the closed rails the venue kept its protocol share first: Meteora keeps 20% of the fee on its curve and in the pool the coin graduated into; Orca keeps 13% of a Whirlpool's fee. Of what reaches the keeper, 80% goes into the coin's agent wallet and 20% is GrokPad's (since 2026-10-23; nothing is paid to the dev's own wallet directly, and the mix a dev used to choose across their wallet, the agent wallet and a buyback-and-burn is gone). The agent wallet is the dev's money: deposits come back any time, and fee earnings unlock 72 hours after launch, then up to 5% of the balance a day, only ever to the dev's wallet.
The quote is SPCX. Since 2026-10-28 every pump.fun coin is quoted in SPCX ("SpaceX - Backpack Securities", mint SPCXxcqXj6e5dJDVNovHN8744zkbhM2bYudU45BimGb): SpaceX stock tokenized by Backpack as a Token-2022 mint, which pump.fun lists as a quote mint. Buys, sells, the dev's first buy and the creator fees are all in SPCX, so every creator fee the keeper collects and pays arrives as SPCX: pump-fees and pump-collect are quote-aware, and pump-pay pays a round in the coin's quote under the mint's own token program. GROKPAD_PUMP_QUOTE_MINT names the quote (SPCX on mainnet; unset means SOL, which test networks use, and a pump.fun coin launched before the switch keeps the quote it was born with: the coin's JSON carries quote). The agent wallet's JSON carries quote, its SPCX balance, and the dev withdraws it with POST /tokens/{mint}/withdraw and kind: "quote". The desk trades with the SOL the dev deposits into the agent wallet; converting the wallet's SPCX income into trading SOL is not built. A GrokPad coin is not SpaceX and is affiliated with neither SpaceX nor Backpack. On Meteora every fee arrived in SOL (or ORCA, for the coin quoted in it). The dev's first buy at launch lands in the agent wallet as well (pump.fun: moved by the second transaction; Meteora: the buy's receiver), and is theirs to withdraw any time: POST /tokens/{mint}/withdraw with kind coins, built by the worker's wallet-send-coins and signed by the gateway only when it is that one transfer to the dev (sign_coin_send).
The creator fee is the dev's pick. On pump.fun the dev sets it at launch: 0.1% to 3% in 0.1% steps, 1% by default (pump.fun's creator_fee_bps, capped by pump.fun at 3%; GROKPAD_PUMP_CREATOR_FEE_BPS="10,300,100" is min, max, default; POST /launch/prepare takes creator_fee_bps, GET /launch/config reports the range as creator_fee {min_bps, max_bps, step_bps, default_bps}, and the coin's JSON carries creator_fee_pct). pump.fun's own trade fee sits on top of it and is pump.fun's. On the closed rails it was the dev's choice on Meteora (0.5% to 10%, 2% by default, fixed for the coin's life) and one of Orca's tiers on the Orca rail: 0.30%, 0.65%, 1% or 2%, fixed or adaptive (adaptive adds a surcharge while the price swings hard, capped by Orca at 10%). Neither the dev nor GrokPad can change a coin's fee after launch.
Environment: GROKPAD_SPLIT_DEV_BPS (0), _AGENT_BPS (8000), _TREASURY_BPS (2000), must total 10000; GROKPAD_PUMP_QUOTE_MINT (SPCX on mainnet; unset = SOL) and GROKPAD_PUMP_CREATOR_FEE_BPS (10,300,100), the pump.fun rail's; GROKPAD_FEE_TIERS (64,96,128,256,1025,1031,1032,1033), GROKPAD_DEFAULT_FEE_TIER (256), both the closed Orca rail's. GET /launch/config and GET /tokens/{mint}/fee-mix report the split (split, creator_bps 0, agent_bps 8000, treasury_bps 2000); POST /tokens/{mint}/fee-mix, which set a dev's mix, answers 400 now.
Buyback & burn of a coin by its dev was retired with the fee mix on 2026-10-23. The Orca rail's rounds before that (orca-buyback: an exact-output swap on the coin's own pool, then a burn) remain as buyback_burn ledger rows with their transactions.
What GrokPad earns
On pump.fun, every coin's rail since 2026-10-28, the creator fee is the dev's pick, 0.1% to 3% of each trade (1% by default), paid in SPCX on top of pump.fun's own trade fee, and the 80 / 20 split is of it: at the default 1%, for every 1,000 SPCX traded, 8 SPCX reach the agent wallet and 2 SPCX are GrokPad's; at 3%, 24 and 6. GrokPad earns nothing else from a pump.fun coin. The tables below are the closed rails' numbers, kept for the coins still on them.
On the Meteora rail (closed 2026-10-28) the curve and the DAMM v2 pool it graduates into charge the fee the dev picked at launch (one partner config per quote and fee, made by the keeper the first time a fee is used). Meteora keeps 20% of it, and GrokPad's 20% is of the rest, so GrokPad earns fee × 0.8 × 0.2 of volume, all of it in SOL (DBC and DAMM v2 collect fees in the quote token), none of it arriving as the coin; the agent wallet's 80% is fee × 0.8 × 0.8.
| Fee picked | per 1,000 SOL traded: the agent wallet | GrokPad |
|---|---|---|
| 0.5% | 3.20 SOL | 0.80 SOL |
| 1% | 6.40 SOL | 1.60 SOL |
| 2% (default) | 12.80 SOL | 3.20 SOL |
| 3% | 19.20 SOL | 4.80 SOL |
| 5% | 32.00 SOL | 8.00 SOL |
| 10% | 64.00 SOL | 16.00 SOL |
On the Orca rail (closed 2026-10-28), Orca's protocol share is 13% of every pool fee (defaultProtocolFeeRate 1300 on the main config; orca-tiers prints it). GrokPad's 20% is of the 87% that reaches the locked position, so for every 1,000 SOL traded in a coin's pool:
| Pool fee tier | Whole fee | Orca (13%) | Agent wallet's 80% | GrokPad's 20% |
|---|---|---|---|---|
| 0.30% | 3.00 SOL | 0.39 | 2.09 | 0.52 SOL |
| 0.65% | 6.50 SOL | 0.85 | 4.52 | 1.13 SOL |
| 1.00% | 10.00 SOL | 1.30 | 6.96 | 1.74 SOL |
| 2.00% (default) | 20.00 SOL | 2.60 | 13.92 | 3.48 SOL |
Rule of thumb at the Orca default tier: GrokPad earns 0.348% of an Orca coin's volume. Adaptive tiers charge more while the price swings (up to Orca's 10% cap), so a volatile first hour can pay up to five times the table.
Orca's tiers top out at 2% fixed (plus the adaptive surcharge), so higher fixed fees existed only on the Meteora rail.
Four things that shape the real number (the first two on the Orca rail only):
- On Orca, half of it arrives as the coin, not SOL. Orca charges the fee on the token going in: buys pay in SOL, sells pay in the coin. The keeper pays the dev's and agent's coin shares out and keeps GrokPad's coin share in its own token accounts; nothing sells it. Count the SOL side (buys) as the cash income.
- On Orca, other LPs dilute it. Anyone can add liquidity to a Whirlpool; fees go pro rata to in-range liquidity, and a concentrated position near the price earns more per SOL than the keeper's full-range one.
- Nothing is earned at launch. What the dev pays to launch goes to rent on the chain, not to GrokPad; the first buy pays the pool fee like any trade. The keeper's own running costs (tick arrays, payee accounts, finishing launches) come out of its float. GrokPad takes no cut of the agents' hunting trades or their LP desks.
- The native token's buybacks spend this income (its own pool's share excepted). At
GROKPAD_NATIVE_BUYBACK_BPS=10000all of GrokPad's SOL income buys the token back and nothing replenishes the keeper's float or pays for inference; a lower share (8000 leaves 20% of the income) keeps ops funded from fees (native-token.md).
The keeper's books
- A collect is a round (
fee_rounds), recorded from the collect transaction's measured amounts, idempotent on its signature.collecting(sent, not yet measured) →collected→paying→paid. - Paying claims the round first (
collected → paying, one compare-and-set), so two passes can never pay one round. A payout whose outcome is unknown stayspayingwith its signature and is settled from the chain; one that failed, or that cannot land any more, goes back tocollectedand is paid again. - An empty wallet cannot receive SOL below the rent-exempt minimum, so a small share for one waits (carried per coin) and goes out with a later round.
- The sweep subtracts everything the keeper owes (unpaid dev and agent shares, carried amounts) before moving GrokPad's share to ops.
- Every payout is a
fee_shareledger row (role dev / agent / treasury) with its signature; coin amounts indetail.
Rules
- The server signs nothing unless
GROKPAD_ONCHAIN_SIGNING=true, and on mainnet only withGROKPAD_ALLOW_MAINNET_SIGNING=truetoo. - Launches are open only when the keeper key, signing, the keystore (agent wallets) and the chain worker are all there (
GET /launch/config). - A pump.fun launch is recorded only when the chain shows the coin on pump.fun's curve with the signed-in wallet as its creator and its fee-sharing config paying the keeper ("pump.fun" under The rails, and the security model below).
- On the Orca rail (closed) a launch was recorded only if the chain shows a coin with a fixed 1B supply, no mint or freeze authority, frozen metadata naming the signed-in wallet, and its whole supply locked in its own pool across the curve's positions, all held by the keeper (launch-pipeline.md, "The dynamic bonding curve").
- Agent-wallet secrets are sealed with XSalsa20-Poly1305 under
GROKPAD_KEYSTORE_KEY. On mainnet the gateway refuses to create agent wallets without that key in the environment. The key must be backed up; losing it loses every agent wallet. - The keeper key is the most sensitive secret: it holds every position (whose fees it collects) and the fees between rounds. It cannot withdraw any liquidity, and it cannot redirect the dev share (the payee is frozen in the metadata).
- Deposits are never trusted: the dev submits a signature, the gateway reads the transaction and records only the SOL it actually moved from that wallet to that agent wallet.
- Withdrawals go only to the coin's creator wallet, are serialized per coin, and always leave the account empty or rent-exempt.
- Only keeper commands of the chain worker get the keeper secret; nothing else (agents, the trade builder) ever sees it.
Security model
- Who is a coin's creator is decided by the chain, never by a request. Registering a pump.fun coin needs a wallet session whose wallet equals the coin's on-chain creator (read from its bonding curve, or from its fee-sharing config's admin once a split exists). Creator, source and network are written once and never overwritten. Simulated coins take their creator from the session only.
- Agents cannot reach keys. Every agent worker gets an allowlisted environment (no
GROKPAD_*, no provider key: the model is reached through the gateway's loopback proxy with a per-process bearer, agent-protocol.md, "The model proxy"), and in the container runs as an unprivileged user, so its shell cannot read the gateway's environment, the registry or any key file. The chain worker gets only the RPC URL, plus the treasury secret fordistributealone. - One coin cannot reach another's agents. Every coin's agents run as a uid of their own (and a gid of the same number), handed out by the registry at the coin's first start from
GROKPAD_AGENT_UID_BASE(20000) up, never reused; the gateway, which stays root, switches withsetpriv(a bare number, no passwd entry needed; acoin<uid>entry is added best-effort so git andwhoamiwork in an agent's shell). The coin's workspace root isroot:<its gid> 1770inside/data/tokens(0711), so another coin's uid, with no supplementary groups, cannot enter, read, write or signal anything of it.GROKPAD_AGENT_ISOLATION=sharedruns every coin asGROKPAD_AGENT_USERas before. What a uid cannot stop is loopback TCP: the agent worker 0.1.8 takesPOST /messagefrom any process on the host (no auth token, no unix socket), so the gateway watches every transcript: a user message it never posted means another process drove that worker; the worker is stopped at once (it restarts clean on the next legitimate message) and the event is logged asSECURITY:with the count. Closing the port itself needs an auth token or a unix socket in agent worker. - No double payments. Every outgoing transfer is signed, recorded as
pendingwith its signature, then sent. Pending rows count as paid until the chain settles them; only a transaction that provably never landed is markedfailed. One withdrawal per coin is in flight at a time. - Earnings release at most 5% of the earnings per 24h (not of the balance, so a deposit cannot unlock them).
- Network guard. Signing needs
GROKPAD_ONCHAIN_SIGNING=true, a test network or the explicit mainnet switch, and the RPC's genesis hash must match the configured network. Any spelling other than devnet/testnet/localnet is treated as mainnet. On mainnet the dev key file is never used:GROKPAD_KEYSTORE_KEYis required. - Errors never carry the RPC URL (it can hold an API key); sign-in nonces are per request, capped, and validated.
- Fee splits are verified from chain and only coins whose split includes the agent wallet and the treasury's full share are cranked. Cranks that land but cannot be measured are re-measured later; payouts only count sharing-config shareholders.
The rails
pump.fun is the only rail open to new launches since 2026-10-28. Meteora and Orca are closed: their coins keep trading and keep being paid, and GROKPAD_LAUNCH_VENUES is the only way an operator reopens either.
Meteora's bonding curve (closed for new launches 2026-10-28)
Coins launched on Meteora's bonding curve (docs/launch-pipeline.md, "Launching on Meteora's bonding curve") use the same wallets and books as every other coin: the keeper is the partner config's fee claimer and the owner of the migrated pool's permanently locked position; it collects fees in SOL (dbc-collect) and pays the dev's and the agent's shares (dbc-pay) through the same fee_rounds, carries and ledger rows. Meteora's protocol fee is 20% of every trading fee, taken before the keeper sees anything; the keeper's commands that sign are dbc-config --create, dbc-collect, dbc-pay and dbc-migrate (in KEEPER_COMMANDS). Variables: GROKPAD_LAUNCH_VENUES (default pumpfun since 2026-10-28, meteora before; the rails the launch form offers, the first is its default; meteora and orca are offered only when listed), GROKPAD_DBC_CONFIG (optional; kv keeps the configs the keeper made), GROKPAD_NATIVE_QUOTE_MINT (ORCA on mainnet: what a launch opened with ?quote=orca prices in; its fees and payouts are then in ORCA and its ledger rows carry detail.quote).
pump.fun (the only rail since 2026-10-28)
A coin launches on pump.fun's bonding curve with its dev as the creator, and a per-coin fee-sharing config names GrokPad's keeper as the only shareholder, so every creator fee the coin earns (on the curve and, after it graduates, in its PumpSwap pool) reaches the keeper. The PumpSwap pool is pump.fun's own: GrokPad locks no liquidity on this rail and holds none. The keeper collects the creator fees with the chain worker's distribute (pump-collect, quote-aware like pump-fees) and pays the split out exactly as it does for a Meteora coin, every few minutes and in the coin's quote, SPCX (pump-pay, under the mint's own token program): rounds, carries, 80% to the agent wallet, GrokPad's 20%. The launch itself is built by pump-launch --quote <mint> --creator-fee-bps <n>, and pump-terms [--quote <mint>] reports the curve's terms in that quote (about a 21 SPCX market cap at the start, complete after about 64.5 SPCX has gone in, about 312 SPCX at graduation). pump.fun keeps one creator vault per creator, shared by every coin that creator made, which is why the keeper is never the on-chain creator: the sharing config is per coin and keeps each coin's fees apart. What the keeper cannot do here is change a coin's split on-chain: the config pays the keeper 100% for good, and the 80/20 split lives in the gateway. A launch is two transactions the dev signs in one prompt from the launch page: pump.fun's CreateV2, the coin and its first buy (the mint key signs too), then the fee-sharing config, which also moves the first buy's coins into the coin's agent wallet (pump.fun's buy pays the signer; pump-shares carries the same move when a cut-short launch is finished, capped at what the dev still holds). A coin whose second transaction never landed is live on pump.fun and invisible on the pad until its dev finishes it with just that one transaction (pump-shares) from /launch?finish=<mint>. Since pump.fun's v3 trade instructions (October 2026) a trade's creator fee stays in a bucket on the bonding curve until the permissionless sweep_creator_fee moves it to the creator vault, and the program refuses to change a coin's creator (which creating the config does) or distribute its vault while the bucket holds anything (error 6095 CreatorFeesNotSwept). So the fee-sharing transaction opens with that sweep (and a graduated coin's pool sweep), and the keeper's pump-fees / pump-collect count and sweep the bucket through pump-sdk 4.3.1's helpers; on pump-sdk 2 one bot trade between the launch and the second transaction stranded a coin, live on pump.fun and never recorded. pump-facts reports the bucket as pendingCreatorFee.
Orca Whirlpools (closed for new launches 2026-10-28)
An Orca coin's whole fixed supply sits in its own Whirlpool as one position locked with Orca's permanent lock, held by the keeper (launch-pipeline.md). Trading fees accrue to that position; the keeper collects and pays them out with orca-collect (when uncollected fees reach 0.002 SOL, measured from the transaction) and orca-pay. What the keeper pays from its float (and recovers from GrokPad's 20%): the lookup table once (~0.003 SOL), each new payee's coin account (~0.002 SOL; two per coin), tick arrays as prices climb (~0.002 SOL each), and finishing a launch cut short (~0.032 SOL). A launch itself costs the keeper nothing; the dev pays its rent (~0.038 SOL).
Known risk on this rail: between the coin transaction and the pool transaction, someone could open the coin's pool first and break that launch (the keeper can't finish it then). Sending the launch as one Jito bundle on mainnet would close it.