# Carbium — Full AI Context > Carbium is full-stack Solana infrastructure — bare-metal, no cloud middlemen. > One platform covering the full transaction lifecycle: JSON-RPC, Standard WebSocket (pubsub), > gRPC Full Block streaming, DEX aggregation via the CQ1 engine, and Swap API execution. > Built for developers, trading teams, and MEV bots that require production-grade performance from day one. > > Load this file to enable complete Carbium integration capability: RPC, Standard WebSocket, > Swap API, gRPC streaming, pump.fun sniping, migration from other providers, and production patterns. --- ## Products & Endpoints | Product | Endpoint | Purpose | |---------|----------|---------| | RPC | https://rpc.carbium.io | Solana JSON-RPC reads, writes, subscriptions | | Standard WebSocket | wss://wss-rpc.carbium.io | Native Solana pubsub (account, slot, logs, program, signature) | | gRPC / Stream | wss://grpc.carbium.io | Yellowstone Full Block streaming (~22ms) | | Swap API | https://api.carbium.io | DEX aggregation, quotes, swap execution | | DEX App | https://app.carbium.io | Consumer trading interface | | Docs | https://docs.carbium.io | Full API reference and guides | --- ## Keys & Auth - **RPC + gRPC key:** https://rpc.carbium.io/signup (free, no credit card — one key covers both) - **Swap API key:** https://api.carbium.io/login (free, instant) ```env CARBIUM_RPC_KEY=your_rpc_key_here CARBIUM_API_KEY=your_swap_api_key_here ``` **Security rules:** - Never embed keys in frontend/client-side code - Never commit keys to version control - Rotate keys anytime from the dashboard **RPC auth — two methods:** ``` # Query parameter (recommended for SDK compatibility) https://rpc.carbium.io/?apiKey=YOUR_KEY # Header X-API-KEY: YOUR_KEY ``` **Swap API auth:** ``` X-API-KEY: YOUR_API_KEY ``` --- ## Pricing (RPC) | Tier | Price | Credits/mo | Max RPS | gRPC | |------|-------|------------|---------|------| | Free | $0 | 500K | 10 | — | | Developer | $32/mo | 10M | 50 | — | | Business | $320/mo | 100M | 200 | ✓ | | Professional | $640/mo | 200M | 500 | ✓ | gRPC streaming requires Business tier or above. --- ## Use Case → Product Mapping | Use case | Products needed | |----------|----------------| | Read account data / balances | RPC | | Send a transaction | RPC | | Build a wallet app | RPC + WSS + Swap API | | Get a token swap quote | Swap API | | Execute a swap programmatically | Swap API | | Jito MEV-protected swap | Swap API (bundle endpoint) | | Real-time wallet balance updates | Standard WSS (accountSubscribe) | | Transaction confirmation (no polling) | Standard WSS (signatureSubscribe) | | Program account monitoring (DEX pools, staking) | Standard WSS (programSubscribe) | | Log-based event indexing | Standard WSS (logsSubscribe) | | Slot / block clock / liveness monitoring | Standard WSS (slotSubscribe) | | Full-block transaction streaming | gRPC streaming | | Index all transactions for a program | gRPC streaming | | Monitor a specific wallet (all activity) | gRPC streaming | | Snipe pump.fun tokens (pre-graduation) | gRPC + direct bonding curve tx via RPC | | MEV / arbitrage bot | gRPC + Swap API | | Portfolio tracker | RPC | --- ## 1. RPC — Solana JSON-RPC Standard Solana JSON-RPC 2.0. Drop-in replacement for any provider. ### TypeScript / Node.js (@solana/web3.js) ```typescript import { Connection, PublicKey, LAMPORTS_PER_SOL } from "@solana/web3.js"; const connection = new Connection( `https://rpc.carbium.io/?apiKey=${process.env.CARBIUM_RPC_KEY}`, "confirmed" ); // Get balance const pubkey = new PublicKey("YOUR_WALLET_ADDRESS"); const balance = await connection.getBalance(pubkey); console.log(`Balance: ${balance / LAMPORTS_PER_SOL} SOL`); // Send transaction const sig = await connection.sendRawTransaction(transaction.serialize(), { skipPreflight: false, maxRetries: 3, }); await connection.confirmTransaction(sig, "confirmed"); ``` ### Python (solana-py) ```python from solana.rpc.api import Client from solders.pubkey import Pubkey import os rpc = Client(f"https://rpc.carbium.io/?apiKey={os.environ['CARBIUM_RPC_KEY']}") pubkey = Pubkey.from_string("YOUR_WALLET_ADDRESS") resp = rpc.get_balance(pubkey) print(f"Balance: {resp.value / 1e9} SOL") ``` ### Python (raw requests) ```python import requests, os res = requests.post( "https://rpc.carbium.io", headers={"X-API-KEY": os.environ["CARBIUM_RPC_KEY"], "Content-Type": "application/json"}, json={"jsonrpc": "2.0", "id": 1, "method": "getHealth"} ) print(res.json()) ``` ### Rust ```rust use solana_client::rpc_client::RpcClient; use solana_sdk::pubkey::Pubkey; use std::str::FromStr; let url = format!( "https://rpc.carbium.io/?apiKey={}", std::env::var("CARBIUM_RPC_KEY").unwrap() ); let client = RpcClient::new(url); let pubkey = Pubkey::from_str("YOUR_WALLET_ADDRESS").unwrap(); let balance = client.get_balance(&pubkey).unwrap(); println!("Balance: {} lamports", balance); ``` ### Commitment levels - `processed` — fastest, rollback risk - `confirmed` — recommended default - `finalized` — guaranteed, slowest --- ## 2. Standard WebSocket — Solana Pubsub Native Solana subscription protocol. Any Solana SDK works out of the box — drop-in compatible. Same API key as HTTP RPC. ### Endpoint ``` wss://wss-rpc.carbium.io/?apiKey=YOUR_RPC_KEY ``` ### WSS vs gRPC — When to Use Which | | Standard WSS | gRPC / Yellowstone | |---|---|---| | **Protocol** | JSON-RPC over WebSocket | Binary protobuf over WS or HTTP/2 | | **What you get** | Account changes, slot updates, logs, signatures | Full atomic blocks, all transactions | | **Tier required** | Developer+ | Business+ | | **Best for** | Wallets, dApps, monitoring specific accounts | MEV bots, indexers, full-block processing | **Rule of thumb:** watching specific accounts/signatures → WSS. Processing all transactions or full blocks → gRPC. ### Subscription Methods | Method | Streams | Use case | |---|---|---| | `accountSubscribe` | Account data changes | Wallet balance updates, PDA state | | `programSubscribe` | All accounts owned by a program | DEX pool state, staking | | `signatureSubscribe` | Transaction confirmation | Confirm sent tx in real time (auto-unsubs) | | `logsSubscribe` | Transaction logs | Program event monitoring | | `slotSubscribe` | New slot numbers | Block clock, liveness | | `rootSubscribe` | Finalized slots | Finality tracking | | `blockSubscribe` | Full block data | Block explorers | | `slotsUpdatesSubscribe` | Slot lifecycle events | Advanced timing | ### TypeScript — accountSubscribe (raw WebSocket) ```typescript import WebSocket from "ws"; const ws = new WebSocket( `wss://wss-rpc.carbium.io/?apiKey=${process.env.CARBIUM_RPC_KEY}` ); ws.on("open", () => { ws.send(JSON.stringify({ jsonrpc: "2.0", id: 1, method: "accountSubscribe", params: [ "YOUR_WALLET_ADDRESS", { encoding: "base64", commitment: "confirmed" }, ], })); }); ws.on("message", (raw) => { const msg = JSON.parse(raw.toString()); if (msg.result !== undefined) { console.log(`Subscribed, id: ${msg.result}`); return; } if (msg.method === "accountNotification") { const { lamports, owner } = msg.params.result.value; console.log(`Balance: ${lamports / 1e9} SOL | Owner: ${owner}`); } }); ``` ### Python — accountSubscribe ```python import asyncio, json, os import websockets async def watch_account(wallet: str): uri = f"wss://wss-rpc.carbium.io/?apiKey={os.environ['CARBIUM_RPC_KEY']}" async with websockets.connect(uri) as ws: await ws.send(json.dumps({ "jsonrpc": "2.0", "id": 1, "method": "accountSubscribe", "params": [wallet, {"encoding": "base64", "commitment": "confirmed"}], })) ack = json.loads(await ws.recv()) print(f"Subscribed: {ack['result']}") async for raw in ws: msg = json.loads(raw) if msg.get("method") == "accountNotification": val = msg["params"]["result"]["value"] print(f"Balance: {val['lamports'] / 1e9} SOL") asyncio.run(watch_account("YOUR_WALLET_ADDRESS")) ``` ### TypeScript — signatureSubscribe (tx confirmation) ```typescript ws.on("open", () => { ws.send(JSON.stringify({ jsonrpc: "2.0", id: 1, method: "signatureSubscribe", params: ["YOUR_TX_SIGNATURE", { commitment: "confirmed" }], })); }); ws.on("message", (raw) => { const msg = JSON.parse(raw.toString()); if (msg.method === "signatureNotification") { const { err } = msg.params.result.value; console.log(err ? `Failed: ${err}` : "Confirmed!"); ws.close(); // auto-unsubscribes after first notification } }); ``` ### TypeScript — logsSubscribe (program events) ```typescript ws.on("open", () => { ws.send(JSON.stringify({ jsonrpc: "2.0", id: 1, method: "logsSubscribe", params: [ { mentions: ["6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"] }, { commitment: "confirmed" }, ], })); }); ws.on("message", (raw) => { const msg = JSON.parse(raw.toString()); if (msg.method === "logsNotification") { const { signature, logs } = msg.params.result.value; console.log(`Tx: ${signature}`); logs.forEach((log: string) => console.log(" ", log)); } }); ``` ### Using @solana/web3.js (Recommended) ```typescript import { Connection, PublicKey } from "@solana/web3.js"; const connection = new Connection( `https://rpc.carbium.io/?apiKey=${process.env.CARBIUM_RPC_KEY}`, { commitment: "confirmed", wsEndpoint: `wss://wss-rpc.carbium.io/?apiKey=${process.env.CARBIUM_RPC_KEY}`, } ); // Account changes connection.onAccountChange( new PublicKey("YOUR_WALLET"), (info, ctx) => console.log(`Balance: ${info.lamports / 1e9} SOL at slot ${ctx.slot}`), "confirmed" ); // Transaction confirmation connection.onSignature( "YOUR_TX_SIG", (result, ctx) => console.log(result.err ? "Failed" : `Confirmed at slot ${ctx.slot}`), "confirmed" ); // Program account changes connection.onProgramAccountChange( new PublicKey("PROGRAM_ID"), (info, ctx) => console.log(`Account ${info.accountId} changed`), "confirmed" ); // Logs connection.onLogs( new PublicKey("PROGRAM_ID"), (logs) => logs.logs.forEach(l => console.log(l)), "confirmed" ); // Slot connection.onSlotChange((info) => console.log(`Slot: ${info.slot}`)); ``` ### Reconnection (Required for Production) ```typescript class CarbiumWSS { private ws: WebSocket | null = null; private backoff = 1000; connect() { this.ws = new WebSocket(`wss://wss-rpc.carbium.io/?apiKey=${process.env.CARBIUM_RPC_KEY}`); this.ws.on("open", () => { this.backoff = 1000; this.subscribe(); }); this.ws.on("close", () => { setTimeout(() => this.connect(), this.backoff); this.backoff = Math.min(this.backoff * 2, 30_000); }); this.ws.on("message", (raw) => this.handle(JSON.parse(raw.toString()))); setInterval(() => this.ws?.readyState === 1 && this.ws.ping(), 30_000); } private subscribe() { /* re-subscribe all after reconnect */ } private handle(msg: any) { /* route by msg.method */ } } ``` ```python import asyncio, json, os import websockets from websockets.exceptions import ConnectionClosed URI = f"wss://wss-rpc.carbium.io/?apiKey={os.environ['CARBIUM_RPC_KEY']}" async def run(): backoff = 1 while True: try: async with websockets.connect(URI, ping_interval=30, ping_timeout=10) as ws: backoff = 1 await ws.send(json.dumps({"jsonrpc": "2.0", "id": 1, "method": "slotSubscribe"})) async for raw in ws: msg = json.loads(raw) if msg.get("method") == "slotNotification": print(f"Slot: {msg['params']['result']['slot']}") except (ConnectionClosed, OSError) as e: print(f"Disconnected ({e}), retry in {backoff}s") await asyncio.sleep(backoff) backoff = min(backoff * 2, 30) asyncio.run(run()) ``` ### Unsubscribe | Subscribe | Unsubscribe | |---|---| | `accountSubscribe` | `accountUnsubscribe` | | `programSubscribe` | `programUnsubscribe` | | `signatureSubscribe` | `signatureUnsubscribe` (auto after first) | | `logsSubscribe` | `logsUnsubscribe` | | `slotSubscribe` | `slotUnsubscribe` | | `blockSubscribe` | `blockUnsubscribe` | | `rootSubscribe` | `rootUnsubscribe` | --- ## 3. Swap API — DEX Aggregation (CQ1) Powered by CQ1: sub-ms quotes, ~10ms chain-to-queryable, Jito bundling built in. > Note: Quote endpoint uses `src_mint`/`dst_mint`. Swap endpoint uses `fromMint`/`toMint`. Parameter names differ between endpoints. ### Get a Quote ``` GET https://api.carbium.io/api/v2/quote Header: X-API-KEY: YOUR_API_KEY ``` | Param | Required | Description | |-------|----------|-------------| | `src_mint` | Yes | Source token mint address | | `dst_mint` | Yes | Destination token mint address | | `amount_in` | Yes | Amount in smallest unit (lamports) | | `slippage_bps` | No | Slippage in basis points (default: 50) | ```bash curl -s "https://api.carbium.io/api/v2/quote\ ?src_mint=So11111111111111111111111111111111111111112\ &dst_mint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\ &amount_in=1000000000\ &slippage_bps=100" \ -H "X-API-KEY: YOUR_API_KEY" ``` ### Execute a Swap ``` GET https://api.carbium.io/api/v2/swap Header: X-API-KEY: YOUR_API_KEY Header: Accept: text/plain ``` | Param | Required | Description | |-------|----------|-------------| | `fromMint` | Yes | Input token mint | | `toMint` | Yes | Output token mint | | `amount` | Yes | Input amount in smallest unit | | `slippage` | Yes | Slippage in basis points | | `provider` | No | Routing preference (e.g. "raydium") | Returns base64-encoded serialized transaction. Deserialize → sign → send via RPC. ### Jito MEV-protected swap ``` GET https://api.carbium.io/api/v2/swap/bundle ``` Same parameters as `/swap`. Routes via Jito for MEV protection. No separate Jito SDK needed. ### Full TypeScript swap flow ```typescript import { Connection, VersionedTransaction } from "@solana/web3.js"; const API_KEY = process.env.CARBIUM_API_KEY!; const RPC_KEY = process.env.CARBIUM_RPC_KEY!; // 1. Quote const quote = await fetch( `https://api.carbium.io/api/v2/quote` + `?src_mint=So11111111111111111111111111111111111111112` + `&dst_mint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` + `&amount_in=1000000000&slippage_bps=100`, { headers: { "X-API-KEY": API_KEY } } ).then(r => r.json()); // 2. Swap transaction const { transaction } = await fetch( `https://api.carbium.io/api/v2/swap` + `?fromMint=So11111111111111111111111111111111111111112` + `&toMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` + `&amount=1000000000&slippage=100`, { headers: { "accept": "text/plain", "X-API-KEY": API_KEY } } ).then(r => r.json()); // 3. Deserialize → sign → send const connection = new Connection(`https://rpc.carbium.io/?apiKey=${RPC_KEY}`, "confirmed"); const tx = VersionedTransaction.deserialize(Buffer.from(transaction, "base64")); // tx.sign([yourKeypair]); const sig = await connection.sendRawTransaction(tx.serialize(), { maxRetries: 3 }); await connection.confirmTransaction(sig, "confirmed"); console.log("Swap confirmed:", sig); ``` ### Python swap flow ```python import httpx, os API = "https://api.carbium.io/api/v2" KEY = os.environ["CARBIUM_API_KEY"] quote = httpx.get(f"{API}/quote", params={ "src_mint": "So11111111111111111111111111111111111111112", "dst_mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "amount_in": 1_000_000_000, "slippage_bps": 100 }, headers={"X-API-KEY": KEY}).json() print(quote) ``` --- ## 4. gRPC Streaming (Business tier+) Yellowstone-compatible Full Block streaming. ~22ms latency. Atomic complete blocks — no shred reassembly needed. Same RPC key for both RPC and gRPC. ### Endpoints ``` WebSocket: wss://grpc.carbium.io/?apiKey=YOUR_RPC_KEY HTTP/2: https://grpc.carbium.io (header: x-token: YOUR_RPC_KEY) ``` ### TypeScript — transaction subscription ```typescript import WebSocket from "ws"; const ws = new WebSocket( `wss://grpc.carbium.io/?apiKey=${process.env.CARBIUM_RPC_KEY}` ); ws.on("open", () => { ws.send(JSON.stringify({ jsonrpc: "2.0", id: 1, method: "transactionSubscribe", params: [ { vote: false, failed: false, accountInclude: ["YOUR_PROGRAM_ID"], accountExclude: [], accountRequired: [], }, { commitment: "confirmed", encoding: "base64", transactionDetails: "full", showRewards: false, maxSupportedTransactionVersion: 0, }, ], })); }); ws.on("message", (raw) => { const msg = JSON.parse(raw.toString()); if (msg.method === "transactionNotification") { const { signature, slot } = msg.params.result; console.log(`tx ${signature} in slot ${slot}`); } }); // Always reconnect — use exponential backoff ws.on("close", (code) => connectWithReconnect()); // Keepalive — required every 30s setInterval(() => ws.ping(), 30_000); ``` ### Python — async subscription ```python import asyncio, json, os import websockets PROGRAM_ID = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P" async def subscribe(): uri = f"wss://grpc.carbium.io/?apiKey={os.environ['CARBIUM_RPC_KEY']}" async with websockets.connect(uri) as ws: await ws.send(json.dumps({ "jsonrpc": "2.0", "id": 1, "method": "transactionSubscribe", "params": [ {"vote": False, "failed": False, "accountInclude": [PROGRAM_ID]}, {"commitment": "confirmed", "encoding": "base64", "transactionDetails": "full", "showRewards": False, "maxSupportedTransactionVersion": 0}, ], })) async for message in ws: data = json.loads(message) if data.get("method") == "transactionNotification": print(f"tx: {data['params']['result']['signature'][:20]}...") asyncio.run(subscribe()) ``` ### Rust (Yellowstone client) ```rust use yellowstone_grpc_client::GeyserGrpcClient; let mut client = GeyserGrpcClient::connect( "https://grpc.carbium.io", Some("YOUR_RPC_KEY"), // passed as x-token header None, )?; let (_tx, mut stream) = client.subscribe().await?; ``` ### Subscription filter fields | Field | Type | Description | |-------|------|-------------| | `vote` | bool | Include vote transactions | | `failed` | bool | Include failed transactions | | `accountInclude` | string[] | Include txs involving ANY of these accounts | | `accountExclude` | string[] | Exclude txs involving these accounts | | `accountRequired` | string[] | Include only txs involving ALL of these accounts | ### Unsubscribe ```json {"jsonrpc": "2.0", "id": 2, "method": "transactionUnsubscribe", "params": [SUBSCRIPTION_ID]} ``` --- ## 5. Pump.fun Token Sniping The Swap API cannot route pump.fun / Raydium CPMM tokens. Use gRPC to detect launches + direct bonding curve transactions via RPC. Requires Business tier. ### Constants ```typescript const PUMP_PROGRAM = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"; const PUMP_GLOBAL = "4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf"; const PUMP_FEE_RECIPIENT = "CebN5WGQ4jvEPvsVU4EoHEpgzq1VV7AbicfhtW4xC9iM"; const PUMP_EVENT_AUTH = "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1"; const GRADUATION_SOL = 85_000_000_000n; const TOTAL_SUPPLY = 1_000_000_000_000_000n; const DISCRIMINATORS = { create: [0xe4, 0x45, 0xa5, 0x2e, 0x51, 0xcb, 0x9a, 0x1d], buy: [0x66, 0x06, 0x3d, 0x12, 0x01, 0xda, 0xeb, 0xea], sell: [0x33, 0xe6, 0x85, 0xa4, 0x01, 0x7f, 0x83, 0xad], }; ``` ### Bonding curve PDA ```typescript function deriveBondingCurve(mint: string): PublicKey { const [address] = PublicKey.findProgramAddressSync( [Buffer.from("bonding-curve"), new PublicKey(mint).toBuffer()], new PublicKey(PUMP_PROGRAM) ); return address; } ``` ### Bonding curve state layout (81 bytes) | Offset | Field | Type | |--------|-------|------| | 0–7 | discriminator | 8 bytes | | 8–15 | virtualTokenReserves | u64 LE | | 16–23 | virtualSolReserves | u64 LE | | 24–31 | realTokenReserves | u64 LE | | 32–39 | realSolReserves | u64 LE | | 40–47 | tokenTotalSupply | u64 LE | | 72 | complete | bool | ### AMM price calculations ```typescript // Buy: tokens received for X SOL input function quoteBuy(curve, solLamports: bigint): bigint { return (curve.virtualTokenReserves * solLamports) / (curve.virtualSolReserves + solLamports); } // Sell: SOL received for X token input function quoteSell(curve, tokens: bigint): bigint { return (curve.virtualSolReserves * tokens) / (curve.virtualTokenReserves + tokens); } ``` ### Buy instruction account order | Index | Account | Access | |-------|---------|--------| | 0 | PUMP_GLOBAL | read | | 1 | PUMP_FEE_RECIPIENT | write | | 2 | mint | read | | 3 | bondingCurve | write | | 4 | bondingCurve ATA | write | | 5 | user ATA | write | | 6 | user / payer | write, signer | | 7 | SystemProgram | — | | 8 | TokenProgram | — | | 9 | AssociatedTokenProgram | — | | 10 | Rent sysvar | — | | 11 | PUMP_EVENT_AUTH | read | | 12 | PUMP_PROGRAM | read | ### Sniping workflow ``` gRPC "Create" event → extract mint → deriveBondingCurve(mint) → [optional] fetchBondingCurve() for price validation → build buy instruction → sendTransaction(skipPreflight: true) ← saves ~200ms → monitor bonding curve state → sell at target % or graduation threshold (~85 SOL) ``` --- ## 6. Migrating from Other Providers ### From Helius / QuickNode / Triton / Alchemy — pure URL swap ```typescript // Before const connection = new Connection("https://mainnet.helius-rpc.com/?api-key=KEY"); const connection = new Connection("https://solana-mainnet.quiknode.pro/TOKEN/"); const connection = new Connection("https://YOUR.mainnet.rpcpool.com/"); // After (all of the above) const connection = new Connection( `https://rpc.carbium.io/?apiKey=${process.env.CARBIUM_RPC_KEY}`, "confirmed" ); ``` ### From Jupiter (Swap API) | Jupiter param | Carbium quote param | Carbium swap param | |---------------|--------------------|--------------------| | `inputMint` | `src_mint` | `fromMint` | | `outputMint` | `dst_mint` | `toMint` | | `amount` | `amount_in` | `amount` | | `slippageBps` | `slippage_bps` | `slippage` | Jito bundling: use `/api/v2/swap/bundle` instead of `/api/v2/swap` — no extra SDK needed. ### From Triton gRPC (Yellowstone) Carbium uses the same Yellowstone protocol. Your existing `transactionSubscribe` / `accountSubscribe` logic works unchanged. Update only the endpoint: ``` wss://grpc.carbium.io/?apiKey=YOUR_RPC_KEY ``` --- ## 7. Production Patterns ### Exponential backoff retry ```typescript const delay = (ms: number) => new Promise(r => setTimeout(r, ms)); async function withRetry(fn: () => Promise, retries = 3, baseMs = 300): Promise { for (let i = 0; i < retries; i++) { try { return await fn(); } catch (e) { if (i === retries - 1) throw e; await delay(baseMs * 2 ** i + Math.random() * 100); } } throw new Error("unreachable"); } const quote = await withRetry(() => fetchQuote(...)); ``` ### gRPC reconnect with backoff ```typescript async function connectWithReconnect() { let backoff = 1000; while (true) { try { await connect(); backoff = 1000; } catch { await delay(backoff); backoff = Math.min(backoff * 2, 30_000); } } } ``` ### Latency optimizations - `skipPreflight: true` saves ~200ms on transaction submission - Pre-build transaction templates — swap in mint at launch time - Fetch bonding curve in parallel while building transaction - WebSocket keepalive ping every 30 seconds to prevent silent disconnects - Check `getSignatureStatus` before retrying `sendTransaction` — avoid duplicate sends ### Timeout guidelines | Operation | Recommended timeout | |-----------|-------------------| | RPC read calls | 5–10 seconds | | Swap quote | 3–5 seconds | | Transaction confirmation | 30–60 seconds (with polling) | --- ## 8. Error Reference ### Failure handling | Failure | Action | |---------|--------| | Quote: no routes found | Retry with wider slippage or different provider | | Simulation failed | Do NOT send — inspect error, log, alert | | sendTransaction failed | Check getSignatureStatus first, then retry | | Transaction not confirmed | Poll with timeout; check blockhash expiry | | Stream disconnected | Reconnect with exponential backoff | | HTTP 429 rate limit | Back off immediately; retry after delay | ### HTTP error codes | Code | Meaning | Action | |------|---------|--------| | 401 | Invalid / missing API key | Verify key and auth format | | 403 | Plan restriction (e.g. gRPC on Free tier) | Upgrade at rpc.carbium.io | | 429 | Rate limit exceeded | Backoff + retry | | 500 | Server error | Retry after 1 second | | 503 | Temporary unavailability | Exponential backoff | ### Pump.fun transaction errors | Error | Cause | Fix | |-------|-------|-----| | Blockhash expired | Tx too slow | Fresher blockhash; reduce latency | | Insufficient funds | Low SOL | Balance must cover amount + ~0.005 SOL fees | | Account not found | Token just created | Retry with 50–100ms delay | | Slippage exceeded | Price moved | Increase maxSolCost or reduce size | --- ## 9. Architecture Notes - **CQ1 Engine:** Carbium's DEX routing — decoupled write/read paths, binary-native state, ~10ms chain-to-queryable, sub-ms quote generation - **Full Blocks vs Shreds:** Carbium streams atomic Full Blocks (~22ms). Shreds (~9ms) require client-side reassembly. Negligible vs ~400ms Solana slot time - **MEV protection:** Built into Swap API — use `/api/v2/swap/bundle` for Jito bundling - **Gasless swaps:** Trade tokens with zero SOL balance via Swap API - **Bare-metal:** No cloud middlemen — dedicated hardware, no noisy neighbours --- ## Common Token Mints | Token | Mint | |-------|------| | SOL (wrapped) | `So11111111111111111111111111111111111111112` | | USDC | `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` | | USDT | `Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB` | --- ## Reference Links | Resource | URL | |----------|-----| | Ecosystem overview | https://docs.carbium.io/docs/the-carbium-ecosystem | | RPC quickstart | https://docs.carbium.io/docs/quick-start-rpc | | Swap API quickstart | https://docs.carbium.io/docs/quick-start-dex-api | | gRPC guide | https://docs.carbium.io/docs/solana-grpc | | CQ1 engine | https://docs.carbium.io/docs/cq1-engine-overview | | CQ1 data layer | https://docs.carbium.io/docs/cq1-data-layer | | Pricing | https://docs.carbium.io/docs/carbium-rpc-pricing | | API recipes | https://docs.carbium.io/recipes | | Migration guide | https://docs.carbium.io/docs/migration | | FAQ | https://docs.carbium.io/docs/faq | | RPC dashboard | https://rpc.carbium.io | | Swap API dashboard | https://api.carbium.io | | Blog | https://carbium.io/blog | | Discord | https://discord.gg/jW7BUkQS5U | | X / Twitter | https://x.com/carbium | | Telegram | https://t.me/Tolysspider |