Overview
BEAM is the oracle network for Robinhood Chain. It answers one question for smart contracts: what is this asset worth right now, and how do I know?
A set of validators each read prices from their own mix of exchanges and market-data feeds. Every round they sign what they saw, and the network settles on one price per feed with a stake-weighted median. Tunnels package those prices into packets that the validators sign, and the BeamReceiver contract on Robinhood Chain accepts a packet only when the signers hold more than two thirds of total stake.
The design follows the shape of modern oracle networks such as Band Protocol v3: validators submit price signals, the chain aggregates them, and a push model ("tunnels") delivers signed results to destination chains. BEAM is an independent implementation, built for Robinhood Chain and its tokenized stocks.
Sources
BEAM reads only public market data. For crypto, validators draw from eight exchanges:
| Source | What it provides |
|---|---|
| Coinbase, Kraken, Gemini, Bitstamp | USD spot markets |
| OKX, Bitfinex, Binance.US, Crypto.com | USD, USDT and USDC spot markets |
| Market data (two independent endpoints) | US equities incl. pre- and after-hours prints, FX, gold, silver, crude oil |
Each validator is assigned four exchanges plus one market-data endpoint, and the assignments overlap, so every exchange is read by several validators and no validator depends on a single exchange. A validator's own price for a feed is the median across its sources. A quote older than two minutes is ignored.
Rounds & the median
A round runs every 10 seconds. In each round:
- Every validator computes its price for every feed from its own sources.
- It signs its full submission (round number, timestamp and every price, at 8 decimals) with its secp256k1 key.
- For each feed, the network sorts the submissions and takes the stake-weighted median: the price at which half of the participating stake sits on either side.
- A feed is only updated if validators holding more than half of total stake submitted a price for it.
- The round record commits to the previous round's hash, the agreed prices and every validator signature, forming a hash-linked history you can browse in the explorer.
The median makes the result robust: to move a price, a minority of stake cannot do it, and a single bad exchange print is outvoted by the others. The explorer and each feed page show every validator's submission and its distance from the agreed price.
Feed IDs
Each feed has an ID of the form CLASS:SYMBOL-USD. On-chain, the ID is its UTF-8 bytes right-padded to bytes32.
| Prefix | Class | Examples |
|---|---|---|
CS: | Crypto spot | CS:BTC-USD, CS:ETH-USD, CS:SOL-USD |
EQ: | US equities & ETFs | EQ:HOOD-USD, EQ:TSLA-USD, EQ:NVDA-USD, EQ:SPY-USD |
FX: | Currencies | FX:EUR-USD, FX:GBP-USD, FX:JPY-USD |
CM: | Commodities | CM:XAU-USD (gold), CM:XAG-USD, CM:WTI-USD |
All prices are USD with 8 decimals, stored as int256. The full live list is on the Feeds page.
Packets
A packet carries a set of prices from one tunnel. Its hash is computed exactly as the contract computes it:
packetHash = keccak256(abi.encodePacked(
bytes6("BEAMv1"), uint256 chainId, address receiver,
uint64 tunnelId, uint64 seq, uint64 ts,
bytes32[] ids, int256[] prices))
digest = keccak256("\x19Ethereum Signed Message:\n32" ‖ packetHash)
Each validator signs digest with ECDSA over secp256k1 (65-byte r‖s‖v, low-s). Signatures are ordered by increasing signer address, which lets the contract reject duplicates cheaply. Because the chain ID and receiver address are inside the hash, a packet cannot be replayed on another chain or another receiver, and the sequence number stops it from being replayed on the same one.
Tunnels
A tunnel is a standing delivery order. You choose:
- Feeds: 1 to 40 feed IDs.
- Heartbeat: a packet at least every N seconds (30 s to 24 h).
- Deviation: an extra packet as soon as any feed moves more than X basis points from the last delivered price (10 to 5000 bps), at most once every 10 seconds.
- Receiver: the BeamReceiver address the packets are signed for. It defaults to the BEAM receiver on Robinhood Chain.
Opening a tunnel takes a wallet signature over a plain-text request, not a transaction. The signing address becomes the tunnel's owner, and only the owner can pause or resume it. Each wallet can run up to five active tunnels. Tunnel #1, Beam Core, carries every feed and is open to everyone.
BeamReceiver
The contract stores the validator set (address and voting power) and the latest price per feed. relay() is permissionless:
- It recomputes the packet hash and the signed digest.
- It recovers each signer with
ecrecover, requires strictly increasing addresses and sums their power. - It requires that the signing power is more than two thirds of total power, that
seqis greater than the tunnel's last sequence, and that the timestamp is not in the future. - It stores each price, never overwriting a newer price with an older one.
Source: BeamReceiver.sol. A relay of four prices with nine signatures costs about 307k gas.
Reading prices
interface IBeam {
function getPrice(bytes32 id) external view returns (int256 price, uint64 ts);
function getPriceNoOlderThan(bytes32 id, uint256 maxAge) external view returns (int256 price, uint64 ts);
function decimals() external pure returns (uint8); // 8
}
// a TSLA price no older than two minutes
(int256 p, ) = IBeam(BEAM).getPriceNoOlderThan(bytes32("EQ:TSLA-USD"), 120);
Always use getPriceNoOlderThan in anything that moves money, with a maxAge that matches your tunnel's heartbeat.
Open validators
The BEAM validator set is permissionless. Next to the genesis validators, anyone can run an open validator:
- In a browser tab: the Run a validator page creates a validator key locally, binds it to your wallet with one signature, and starts validating. Your browser reads Coinbase, Kraken, OKX, Gemini, Binance.US, Crypto.com and Bitstamp directly.
- Headless:
OWNER_KEY=0x… node node/beam-node.js --name mynode --api https://… --stocksruns the same validator 24/7 on any machine with Node.js.--stocksadds US equities, FX and metals.
Every round an open validator signs its own prices, which enter the stake-weighted median with its voting power. When a tunnel produces a packet, the packet stays open for co-signatures for four seconds: each open validator recomputes the packet hash itself, compares every price it can observe with its own view (within 1%), and signs only if it agrees. The finalized packet carries every signature, sorted by signer address, and its quorum is measured against the full active set, so validators that stay silent count against it.
Accountability is automatic. A submission more than 1.5% from the agreed price is a strike; five strikes within 200 rounds jails the validator for 30 minutes. A validator is active while it keeps checking in, at most 45 seconds apart. One validator per wallet, and new validators per network are rate limited.
Relaying
BEAM runs a relayer that submits packets for the BEAM receiver as they are signed. Relaying is open to anyone: take any packet from the API, ABI-encode relay(tunnelId, seq, ts, ids, prices, sigs) and send it. The contract does all the checking, so a relayer cannot alter a price; it can only deliver or not deliver. Running a second relayer is the simplest way to make delivery to your own contract independent of ours.
Verifying
The Verify page loads any packet, recomputes its hash in your browser with the same encoding as the contract, recovers every signature with secp256k1 and sums the stake of the signers against the published validator set. The code is plain JavaScript you can read: beam-crypto.js.
API
| Endpoint | Returns |
|---|---|
GET /api/status | Round, head hash, validator set with power, source health, receiver, relayer |
GET /api/feeds | Every feed with price, 24h change, spread, validator count, sparkline |
GET /api/feed/:id?range=1h|6h|1d|7d | One feed with candles, per-validator submissions and raw source quotes |
GET /api/validators | Stake, power, sources, uptime, average deviation |
GET /api/rounds, /api/round/:n | Recent rounds; one round with every signed submission |
GET /api/tunnels, /api/tunnel/:id | Tunnels; one tunnel with its latest packets |
GET /api/packets?tunnel=, /api/packet/:tunnel/:seq | Signed packets, ready to relay or verify |
POST /api/tunnels | Open a tunnel: { message, signature } |
FAQ
What is an oracle, in one sentence?
A way for a smart contract to learn something from outside its chain, here a price, along with evidence that it was not made up.
Why a median and not an average?
An average can be dragged by one extreme value. A median ignores outliers until more than half of the stake agrees on them, which is exactly the property you want from a price.
Why weight by stake?
Stake is what a validator puts behind its work. Weighting by stake means influence over a price costs something, and the same weights decide whether a packet reaches quorum on-chain.
Why more than two thirds?
It is the standard threshold for Byzantine fault tolerance: as long as less than one third of stake is faulty, no invalid packet can gather enough signatures.
Do stock feeds update when markets are closed?
Equity feeds follow official prints, including pre-market and after-hours sessions. Outside those sessions the price holds at the last print and the timestamp shows how old it is, which is why getPriceNoOlderThan exists.
Can the relayer change a price?
No. The prices are inside the signed hash. Changing any byte breaks every signature and the contract rejects it, as you can confirm on the Verify page by editing a packet.
Can I use BEAM prices off-chain?
Yes. The API is open, and every packet carries its own proof, so an off-chain system can verify it with the same code the Verify page uses.
What does a tunnel cost?
Opening and running a tunnel is free today. Gas for on-chain delivery is paid by whoever relays.
How do validators join?
Anyone can run an open validator from the Run a validator page or with the headless node. Open validators, the genesis set, their power, uptime and accuracy are all listed on the Validators page.
Where is the code?
The contract and the verification library are served directly from this site. Links are in the footer.