Developer Documentation
JoFi is a high-performance execution infrastructure and JSON-RPC gateway built specifically for Robinhood Chain (Chain ID: 4663). It provides ultra-fast access to Nitro sequencer blocks, zero-gas revert protection, live sequencer streaming, and privacy-preserving backrun MEV rebates.
Network Specifications
Robinhood Chain is an Arbitrum Nitro (Orbit L2) rollup featuring sub-second (~100 ms) sequencer block generation. Use the parameters below to configure your clients and scripts:
- HTTP RPC:
https://gateway/rpc/$KEYor/rpcwith headerx-api-key: $KEY - Sequencer Feed (WebSocket):
wss://gateway/feed/$KEY - Backrun Auction (WebSocket):
wss://gateway/auction/$KEY
Quickstart & SDK Integration
Get an API key on the Dashboard with your Web3 wallet, then connect using any standard Ethereum library.
curl -s https://gateway/rpc/$KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_blockNumber",
"params": []
}'
import { createPublicClient, http, defineChain } from "viem";
export const robinhoodChain = defineChain({
id: 4663,
name: "Robinhood Chain",
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
rpcUrls: {
default: { http: ["https://gateway/rpc/" + process.env.JOFI_KEY] },
},
});
const client = createPublicClient({
chain: robinhoodChain,
transport: http(),
});
const blockNumber = await client.getBlockNumber();
console.log("Current block:", blockNumber);
import { JsonRpcProvider } from "ethers";
const provider = new JsonRpcProvider(
`https://gateway/rpc/${process.env.JOFI_KEY}`,
{ chainId: 4663, name: "robinhood" }
);
const blockNumber = await provider.getBlockNumber();
console.log("Latest Robinhood Chain block:", blockNumber);
import os
from web3 import Web3
key = os.getenv("JOFI_KEY")
rpc_url = f"https://gateway/rpc/{key}"
w3 = Web3(Web3.HTTPProvider(rpc_url))
assert w3.is_connected(), "Could not connect to JoFi Gateway"
print("Robinhood Chain Block Number:", w3.eth.block_number)
print("Latest Gas Price (wei):", w3.eth.gas_price)
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/ethereum/go-ethereum/ethclient"
)
func main() {
rpcURL := fmt.Sprintf("https://gateway/rpc/%s", os.Getenv("JOFI_KEY"))
client, err := ethclient.Dial(rpcURL)
if err != nil {
log.Fatalf("Failed to connect to JoFi: %v", err)
}
block, err := client.BlockNumber(context.Background())
if err != nil {
log.Fatalf("Failed to retrieve block: %v", err)
}
fmt.Printf("Latest Robinhood Chain Block: %d\n", block)
}
use alloy::providers::{Provider, ProviderBuilder};
#[tokio::main]
async fn main() -> Result<(), Box> {
let key = std::env::var("JOFI_KEY").expect("JOFI_KEY not set");
let rpc_url = format!("https://gateway/rpc/{}", key).parse()?;
let provider = ProviderBuilder::new().on_http(rpc_url);
let block_number = provider.get_block_number().await?;
println!("Robinhood Block Number: {}", block_number);
Ok(())
}
Wallet Configuration (MetaMask & Rabby)
Add Robinhood Chain directly to your wallet using these parameters:
| Setting | Value |
|---|---|
| Network Name | Robinhood Chain (JoFi) |
| New RPC URL | https://gateway/rpc/YOUR_API_KEY |
| Chain ID | 4663 |
| Currency Symbol | ETH |
| Block Explorer URL | https://explorer.mainnet.chain.robinhood.com |
API Keys & Authentication
JoFi uses non-custodial wallet sign-in (EIP-191 personal_sign with single-use cryptographic nonces). We never hold or request your private keys.
- Key Format: 32-byte hexadecimal strings (
jofi_...). API keys are hashed with SHA-256 before storage; the plain text is only shown once at creation. - Transmission: Include your key either as a URL path segment (
/rpc/{KEY}) or in the HTTP header (x-api-key: {KEY}). - Batch Requests: JSON-RPC batches up to 100 calls per request are supported.
- Forbidden Methods: Node-custodial and administrative calls (such as
eth_sendTransaction,eth_sign,personal_*,admin_*) are rejected. Transactions must be signed locally on the client and dispatched viaeth_sendRawTransaction.
Revert Protection (Zero-Gas Failure Filter)
In sub-second rollups, pending state shifts quickly. A transaction sent to the sequencer that fails due to slippage, expired deadlines, or depleted allowance burns gas fees without doing anything. JoFi eliminates this wasted capital.
How Simulation Works
Whenever you call eth_sendRawTransaction:
- Local Decoding: The gateway decodes the raw RLP or typed transaction, recovering the sender, nonce, value, gas limit, and calldata.
- Nonce Inspection: The sender's pending nonce is checked via
eth_getTransactionCount. Nonce reuse or nonce gaps are intercepted immediately. - State Simulation: An
eth_callsimulation runs against the latest sequencer state. - Verdict: If the simulation fails, JoFi returns error code
-32003with the decoded revert string or Solidity panic code. The transaction is never broadcast, and zero gas is spent.
// Example -32003 Error Response:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32003,
"message": "not sent, would fail: reverted: UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT"
}
}
x-revert-protection: off with your HTTP request.
Backrun MEV Rebates (80/10/10 Split)
Swaps on decentralized exchanges often create transient price discrepancies. Instead of letting predatory bots capture 100% of this arbitrage value for free, JoFi operates a sealed-bid backrun auction that redistributes the value back to the participants.
Fair Value Distribution
| Beneficiary | Share | Description |
|---|---|---|
| User / Trader | 80% | The wallet that initiated the transaction. Direct rebate. |
| Application / Router | 10% | The dApp, bot, or aggregator owning the API key. Monetization stream. |
| JoFi Protocol | 10% | Protocol treasury supporting the gateway infrastructure. |
How dApps Opt In
To enable MEV rebates for your users, simply include the header x-backrun-auction: on when forwarding eth_sendRawTransaction.
- Your user's transaction passes revert protection.
- Connected searchers receive an anonymous hint message over WebSocket.
- Searchers submit their sealed bids within an 80 ms window.
- JoFi validates bids using
eth_simulateV1to ensure atomic execution:[User Tx, Searcher Backrun]. - The winning bundle is forwarded to the sequencer back-to-back. If no searcher bids, your transaction proceeds immediately without delay.
Sequencer Feed (WebSocket Stream)
WebSocket Available on Searcher and Dedicated plans. Robinhood Chain does not have a public mempool; transactions are sequenced directly. JoFi decodes the Nitro sequencer stream in real-time, providing immediate visibility into every executed L2 block.
wscat -c wss://gateway/feed/$KEY
Block Message Format
{
"seq": 78632568, // L2 Block sequence number
"block_hash": "0x4a1b...", // Hash of the executed block
"timestamp": 1790983801, // Sequencer timestamp (seconds)
"received_at": 1790983801.042, // JoFi receive timestamp (sub-ms precision)
"reorg": false, // True if this message replaces an earlier block
"txs": [
{
"hash": "0x5d8c...",
"from": "0x9812...",
"to": "0x5fc5...",
"selector": "0x04e45aaf", // First 4 bytes of calldata
"value": "0x0",
"nonce": 42,
"gas": 150000,
"type": 2
}
]
}
Auction Bidding Protocol (Searcher Guide)
WebSocket Searchers connect to wss://gateway/auction/$KEY to receive auction hints and submit bids.
1. Receiving an Auction Hint
When an auction opens, JoFi broadcasts a hint without exposing user calldata:
{
"type": "hint",
"auction": "7f8b91a2c3d4e5f6",
"user_tx": "0x1234...", // Hash of target transaction
"user": "0xUserWalletAddress", // 80% rebate recipient
"app": "0xAppOwnerAddress", // 10% rebate recipient
"settlement": "0xSettlement...", // Settlement contract address
"to": "0xRouterAddress", // Target contract
"selector": "0x38ed1739", // Function selector (e.g. swapExactTokensForTokens)
"logs": [ // Touched contracts and event topic0s
{ "address": "0xPoolAddress", "topic0": "0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822" }
],
"window_ms": 80
}
2. Submitting a Signed Bid
Respond through the same WebSocket connection before the 80 ms window expires:
{
"type": "bid",
"auction": "7f8b91a2c3d4e5f6",
"tx": "0x02f8...", // Raw signed backrun transaction
"amount_wei": "5000000000000000" // 0.005 ETH bid
}
3. Validation & Rules
- Up to 3 bids per searcher per auction.
- Your backrun transaction must call
pay(bytes32 userTx, address user, address app)on the settlement contract with at leastamount_weiETH attached. - Bids are simulated in descending order of
amount_wei. The highest bid that emits thePaidevent and executes successfully wins.
Searcher Solidity Contract Pattern
Below is a standard reference contract pattern for searchers participating in JoFi backrun auctions:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
interface IBackrunSettlement {
function pay(bytes32 userTx, address user, address app) external payable;
}
contract JoFiSearcherExecutor {
address public immutable owner;
IBackrunSettlement public immutable settlement;
modifier onlyOwner() {
require(msg.sender == owner, "Unauthorized");
_;
}
constructor(address settlementAddress) {
owner = msg.sender;
settlement = IBackrunSettlement(settlementAddress);
}
/// @notice Execute backrun arbitrage and settle rebate
function executeBackrun(
bytes32 userTx,
address user,
address app,
uint256 bidAmount,
bytes calldata arbitrageData
) external onlyOwner payable {
// 1. Perform your custom arbitrage / swap logic here
// ... (e.g. execute DEX swaps, flash loans)
// 2. Pay the bid into the settlement contract
settlement.pay{value: bidAmount}(userTx, user, app);
// 3. Keep remaining profit in contract or send to owner
}
receive() external payable {}
}
Request Units (RU) Pricing Table
JoFi meters usage according to computational cost on the node. The unit schedule is uniform across all tiers:
| Method / Category | Request Units | Notes |
|---|---|---|
Standard Reads (eth_blockNumber, eth_getBalance, eth_call, eth_getTransactionByHash) | 1 | Base read operations |
eth_feeHistory | 2 | Gas history analysis |
eth_estimateGas · eth_createAccessList · eth_getProof | 3 | Light simulation / state proofs |
eth_getLogs (range ≤ 100 blocks or by block hash) | 3 | Short range event logs |
eth_getBlockByNumber / ByHash (with full transaction objects) | 6 | Full block serialization |
eth_getLogs (range ≤ 1,000 blocks) | 10 | Medium range event logs |
eth_sendRawTransaction (includes revert protection simulation) | 12 | RLP decode + pending nonce + eth_call |
eth_getBlockReceipts | 13 | Receipt batch fetching |
eth_getLogs (range ≤ 10,000 blocks) | 25 | Large range event logs |
eth_simulateV1 · debug_traceTransaction · debug_traceCall | 30 | State override & EVM execution trace |
eth_getLogs (> 10,000 blocks) · debug_traceBlockBy* | 50 | Heavy block-level execution traces |
Failed upstream requests (such as node connection drops) are not charged to your account balance.
Error Codes Reference
| Code | Error Name | Resolution |
|---|---|---|
-32001 | Unauthorized (HTTP 401) | Missing, invalid, or revoked API key. Verify key on Dashboard. |
-32003 | Transaction Revert Blocked | Revert protection prevented a failed send. Check the error message for revert strings or panic codes. |
-32005 | Rate Limit or Budget Exceeded (HTTP 429) | Requests per minute (RPM) exceeded, or monthly RU budget exhausted. Top up account with USDG/ETH. |
-32601 | Method Not Allowed | Node administrative or custodial method. Use local client signing. |
-32603 | Upstream Node Unavailable | Upstream sequencer timeout. Safe to retry with exponential backoff. |
Plans, Billing & Deposits
Plans operate on a 30-day billing cycle and are deducted from your prepaid balance.
| Plan | Price | Monthly Budget | Rate Limit | Features |
|---|---|---|---|---|
| Free | $0 | 500,000 RU | 60 RPM | Revert protection, hard stop |
| Builder | $29/mo | 50,000,000 RU | 12,000 RPM | $5.00/M overage, revert protection |
| Pro | $199/mo | 500,000,000 RU | 60,000 RPM | $3.00/M overage, backrun rebates |
| Searcher | $299/mo | 500,000,000 RU | 75,000 RPM | Sequencer feed & auction access |
| Dedicated | $999/mo | 3,000,000,000 RU | 150,000 RPM | Max throughput & full feed access |
Depositing Credit
- USDG (Robinhood Stablecoin): Credited at exact 1:1 USD valuation.
- ETH: Converted to USD value using real-time Uniswap pool pricing (
WETH/USDG 0.01%pool) at the moment of confirmation. - Confirmation Threshold: 10 on-chain confirmations are required before credits become active.
- Deposits must originate from the wallet address you use to log in.
FAQ & Troubleshooting
No. JoFi speaks standard Ethereum JSON-RPC. Simply change your RPC URL in Hardhat, Foundry, viem, or ethers.js.
Robinhood Chain blocks take ~100 ms. Standard polling over HTTP introduces 500ms to 1000ms of lag. The JoFi WebSocket feed delivers decoded blocks the millisecond they are signed by the Nitro sequencer.
You pay nothing. JoFi only broadcasts winning backruns that have been simulated and confirmed. Failed bids are discarded off-chain.
Rebates sent to smart contracts that do not accept plain ETH transfers are tracked in the owed mapping on BackrunSettlement.sol. Call withdraw() from your address at any time to claim your balance.