How it works
Afterpad is a terminal on Robinhood Chain (chain id 4663). It reads the chain directly through public JSON-RPC nodes — no indexer service, no oracle — and builds transactions your wallet signs. There are three feeds behind every page:
- Markets — the 35 issued tokenized stocks with a live Uniswap pool. On-chain price from each pool's
slot0; the exchange print from Yahoo Finance's regular session. Dislocation ischain / exchange − 1. - The tape — every swap on the chain: v4 through the PoolManager's
Swaplog, v3 on each pool. ~40 a second. - New pairs — every pool opened, from the PoolManager's
Initializeand the v3 factory'sPoolCreated. Hundreds an hour.
Custody
None. The server holds no key and has no route that accepts one; the API is read-only. A trade is calldata built in your browser from the quote and sent to your wallet with eth_sendTransaction — you see the exact amounts and approve or reject there. A v3 swap goes to SwapRouter02; a v4 swap to the Universal Router (ERC-20 input via Permit2). The minimum-out in the transaction is what protects you: if the pool cannot fill at least that, it reverts and nothing moves.
The stocks
A ticker is not unique on this chain — squatters copy the symbol and the issuer's name. A pool is on the list only if it passes four tests (npm run discover): DexScreener lists it on Uniswap under the official issue's name; the chain says it has liquidity in range; the chain's price agrees with the aggregator's to 1%; and its dollar price agrees with the exchange's own print to within 8%. HOOD is absent right now because no pool passes — the one that used to has been drained to the edge of its range.
The index
Every swap in the stock pools for a rolling 24 hours, joined to the wallet that made it through the stock token's Transfer in the same transaction (the pool paid the wallet: a buy; the wallet paid the pool: a sell). Kept as hourly buckets per stock per wallet, 5-minute candles per stock, and the newest raw prints. It fills backwards after a start and reports how much it covers; wallet flows are complete once it says 24h.
The risk scan
A screen, not a verdict. Each rule reads a real number and the label is the worst rule that fires; the reasons are listed with it.
| Rule | Caution | Danger |
|---|---|---|
| Depth (DexScreener liquidity) | < $10,000, or not reported yet | < $1,000 |
| Age | < 10 minutes | |
| Hooks (v4) | any hook; a dynamic fee | |
| 24h change | ≤ −30% | ≤ −60% |
| Token | quoted in an unknown token | no decimals(); 20+ buys and no sells in an hour |
API
Everything the terminal reads, as JSON, at /v1 (and /api). No key. 240 requests a minute per address, with X-RateLimit-Limit and X-RateLimit-Remaining on every answer. X-Bell-Burned is 0 until $BELL is live.
| Route | Returns |
|---|---|
GET /v1/config | chain, DEX addresses, $BELL status, fees |
GET /v1/status | chain head, feed health, index coverage, per-node RPC stats |
GET /v1/markets | every stock: chain price, exchange price, dislocation, 24h flow |
GET /v1/markets/:ticker | one stock with flow, top wallets, prints and 5-minute candles |
GET /v1/markets/:ticker/series | the exchange's session candles and the on-chain candles |
GET /v1/tape?limit= | newest swaps on the chain, sized in dollars, with the sender |
GET /v1/prints?ticker= | newest stock prints from the index |
GET /v1/leaders | the most active wallets in the stock pools, 24h |
GET /v1/pairs?limit= | newest pools with depth, turnover, risk and the v4 pool key |
GET /v1/pairs/:id | one pool, freshly enriched |
GET /v1/wallets/:address | live holdings (ETH, USDG, WETH, every stock), 24h flow, prints |
GET /v1/wallets/:address/flow | the 24h flow alone |
GET /v1/tokens/:address | dossier: name, decimals, supply, code size, every pool, risk |
GET /v1/quote?pool=&side=&usd=|amount=&slippage= | a quote and the route (below) |
curl -s https://YOUR-HOST/v1/markets/TSLA | jq '{chain: .chain.usd, exchange: .exchange.price, dislocation, flow: .flow.netUsd}'
Quotes & routes
The quote reads the pool's sqrtPriceX96, in-range liquidity and fee, and computes an exact-input fill with Uniswap's own maths inside the current tick range. It is exact while the trade stays in that range; a trade large enough to cross into thinner liquidity fills worse, and the minimum-out sent with the transaction is the guard. The route names the router, the pool key (v4) or fee tier (v3), the direction, amountIn, amountOut and amountOutMin in base units — everything a wallet needs to build the same calldata the terminal builds.
GET /v1/quote?pool=0x…&side=buy&usd=250&slippage=1
{ "ok": true, "version": "v4", "router": "0x8876…0904", "permit2": "0x0000…8BA3",
"key": { "currency0": "0x…", "currency1": "0x…", "fee": 3000, "tickSpacing": 60, "hooks": "0x0…0" },
"zeroForOne": false, "amountIn": "250000000", "amountOut": "664607…", "amountOutMin": "657961…",
"executionPrice": 0.002658, "priceImpactPct": 0.0027, "warning": null }
$BELL
A fixed-supply ERC-20 with burn and no owner (contracts/Bell.sol), and a staking contract that sets an account's tier and holds nothing but what stakers can withdraw (contracts/BellStaking.sol). Both are written and tested (npm run test:contracts). Deployment is a single command with a funded key — and the site only calls the token live once it sees code at the address. Until then there is no protocol fee, no metering and no tier: you pay the pool's fee and gas, nothing else.