Developer Guide

From Soroban to Stellar RPC: What the Rebrand Means for Developers

The Stellar Development Foundation recently announced a significant change: Soroban RPC is now Stellar RPC. While this might seem like a simple rebrand, it reflects a deeper strategic shift in how developers access and interact with the Stellar network. Let's explore what this means for your applications and how to adapt.

Why the Rebrand?

The transition from "Soroban RPC" to "Stellar RPC" isn't just cosmetic. It represents SDF's vision of a unified data access layer for the entire Stellar ecosystem.

The Old Model:

  • Horizon API for traditional Stellar operations (payments, accounts, offers)
  • Soroban RPC for smart contract interactions
  • Two separate mental models, two sets of endpoints
  • The New Model:

  • Stellar RPC as the unified interface for real-time network state
  • Horizon for historical data and deep indexing
  • Clear separation of concerns: real-time vs. historical
  • What SDF Says

    According to the Stellar roadmap, the unification aims to:

  • Simplify developer experience - One RPC interface for real-time operations
  • Reduce infrastructure complexity - Operators maintain fewer services
  • Enable faster innovation - New features roll out to one service, not two
  • Improve performance - Optimized specifically for real-time state queries
  • What's Actually Changing?

    Endpoint Structure

    The RPC endpoint structure remains largely compatible, but the branding and some method names are evolving:

    // Old approach
    const SOROBAN_RPC_URL = 'https://soroban-rpc.mainnet.stellar.org';
    
    // New unified approach
    const STELLAR_RPC_URL = 'https://stellar-rpc.mainnet.stellar.org';
    // Or via LumenQuery
    const STELLAR_RPC_URL = 'https://rpc.lumenquery.io';

    Method Naming

    Core methods are being standardized:

    Old MethodNew MethodPurpose
    getHealthgetHealthServer health check
    getLatestLedgergetLatestLedgerCurrent ledger info
    simulateTransactionsimulateTransactionTx simulation
    sendTransactionsendTransactionSubmit transaction
    getTransactiongetTransactionTx status by hash
    getLedgerEntriesgetLedgerEntriesRead state data
    getEventsgetEventsQuery events

    Most methods remain unchanged—the focus is on consistency and future expansion.

    New Capabilities

    The rebrand brings additional methods for unified access:

    // New: Get account state directly via RPC
    const response = await fetch(STELLAR_RPC_URL, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        jsonrpc: '2.0',
        id: 1,
        method: 'getLedgerEntries',
        params: {
          keys: [
            // Account ledger key
            'AAAAAAAAAABVc2VyIGFjY291bnQga2V5...'
          ]
        }
      })
    });
    
    // Real-time account balance without Horizon
    const { result } = await response.json();

    Integrating Stellar RPC into Your Stack

    Wallet Integration

    Wallets benefit significantly from unified RPC access:

    // wallet/stellar-rpc-client.ts
    const STELLAR_RPC = 'https://rpc.lumenquery.io';
    
    interface RpcClient {
      getLatestLedger(): Promise<LatestLedger>;
      simulateTransaction(xdr: string): Promise<SimulateResult>;
      sendTransaction(xdr: string): Promise<SendResult>;
      getTransaction(hash: string): Promise<TransactionStatus>;
    }
    
    export async function createRpcClient(apiKey: string): Promise<RpcClient> {
      const call = async (method: string, params: any = {}) => {
        const response = await fetch(STELLAR_RPC, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'X-API-Key': apiKey,
          },
          body: JSON.stringify({
            jsonrpc: '2.0',
            id: Date.now(),
            method,
            params,
          }),
        });
    
        const data = await response.json();
        if (data.error) throw new Error(data.error.message);
        return data.result;
      };
    
      return {
        getLatestLedger: () => call('getLatestLedger'),
        simulateTransaction: (xdr) => call('simulateTransaction', { transaction: xdr }),
        sendTransaction: (xdr) => call('sendTransaction', { transaction: xdr }),
        getTransaction: (hash) => call('getTransaction', { hash }),
      };
    }

    Dashboard Integration

    Real-time dashboards can leverage Stellar RPC for live network state:

    // components/NetworkStatus.tsx
    'use client';
    
    import { useEffect, useState } from 'react';
    
    interface NetworkState {
      ledger: number;
      protocolVersion: number;
      timestamp: number;
    }
    
    export function NetworkStatus() {
      const [state, setState] = useState<NetworkState | null>(null);
    
      useEffect(() => {
        const fetchState = async () => {
          const response = await fetch('/api/stellar-rpc', {
            method: 'POST',
            body: JSON.stringify({ method: 'getLatestLedger' }),
          });
          const { result } = await response.json();
          setState({
            ledger: result.sequence,
            protocolVersion: result.protocolVersion,
            timestamp: Date.now(),
          });
        };
    
        fetchState();
        const interval = setInterval(fetchState, 5000);
        return () => clearInterval(interval);
      }, []);
    
      if (!state) return <div>Loading...</div>;
    
      return (
        <div className="grid grid-cols-3 gap-4">
          <div className="p-4 bg-white rounded-lg shadow">
            <div className="text-sm text-gray-500">Latest Ledger</div>
            <div className="text-2xl font-bold">{state.ledger.toLocaleString()}</div>
          </div>
          <div className="p-4 bg-white rounded-lg shadow">
            <div className="text-sm text-gray-500">Protocol</div>
            <div className="text-2xl font-bold">v{state.protocolVersion}</div>
          </div>
          <div className="p-4 bg-white rounded-lg shadow">
            <div className="text-sm text-gray-500">Updated</div>
            <div className="text-2xl font-bold">
              {new Date(state.timestamp).toLocaleTimeString()}
            </div>
          </div>
        </div>
      );
    }

    Monitoring Tools

    For operations teams monitoring Stellar infrastructure:

    // monitoring/health-checker.ts
    interface HealthStatus {
      rpc: 'healthy' | 'degraded' | 'down';
      latency: number;
      ledgerLag: number;
    }
    
    export async function checkStellarRpcHealth(
      rpcUrl: string
    ): Promise<HealthStatus> {
      const start = Date.now();
    
      try {
        // Check basic health
        const healthResponse = await fetch(rpcUrl, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            jsonrpc: '2.0',
            id: 1,
            method: 'getHealth',
          }),
        });
    
        const latency = Date.now() - start;
        const { result } = await healthResponse.json();
    
        if (result.status !== 'healthy') {
          return { rpc: 'degraded', latency, ledgerLag: -1 };
        }
    
        // Check ledger freshness
        const ledgerResponse = await fetch(rpcUrl, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            jsonrpc: '2.0',
            id: 2,
            method: 'getLatestLedger',
          }),
        });
    
        const { result: ledger } = await ledgerResponse.json();
        const ledgerAge = Date.now() / 1000 - ledger.timestamp;
    
        return {
          rpc: ledgerAge < 10 ? 'healthy' : 'degraded',
          latency,
          ledgerLag: Math.round(ledgerAge),
        };
      } catch (error) {
        return { rpc: 'down', latency: Date.now() - start, ledgerLag: -1 };
      }
    }

    Migration Checklist

    If you're currently using Soroban RPC, here's your migration path:

    1. Update Endpoint URLs

    // Before
    const RPC_URL = process.env.SOROBAN_RPC_URL;
    
    // After
    const RPC_URL = process.env.STELLAR_RPC_URL;

    2. Update Environment Variables

    # .env
    # Before
    SOROBAN_RPC_URL=https://soroban-rpc.mainnet.stellar.org
    
    # After
    STELLAR_RPC_URL=https://rpc.lumenquery.io

    3. Review Method Names

    Most methods are unchanged, but verify against the latest documentation for any deprecations.

    4. Update SDK Versions

    npm update @stellar/stellar-sdk

    The latest SDK versions support both naming conventions during the transition period.

    Best Practices for Unified RPC

    Use Stellar RPC for Real-Time, Horizon for Historical

    // Real-time: Use Stellar RPC
    async function getCurrentLedger() {
      return await stellarRpc.getLatestLedger();
    }
    
    // Historical: Use Horizon
    async function getTransactionHistory(account: string) {
      return await horizon.transactions()
        .forAccount(account)
        .order('desc')
        .limit(100)
        .call();
    }

    Implement Graceful Fallbacks

    async function getAccountBalance(accountId: string) {
      try {
        // Try Stellar RPC first (faster for real-time)
        const entries = await stellarRpc.getLedgerEntries([
          createAccountKey(accountId)
        ]);
        return parseBalance(entries);
      } catch (error) {
        // Fall back to Horizon
        const account = await horizon.loadAccount(accountId);
        return account.balances;
      }
    }

    Cache Appropriately

    const cache = new Map<string, { data: any; expires: number }>();
    
    async function cachedRpcCall(method: string, params: any, ttl = 5000) {
      const key = `${method}:${JSON.stringify(params)}`;
      const cached = cache.get(key);
    
      if (cached && cached.expires > Date.now()) {
        return cached.data;
      }
    
      const result = await stellarRpc.call(method, params);
      cache.set(key, { data: result, expires: Date.now() + ttl });
      return result;
    }

    Conclusion

    The Soroban to Stellar RPC rebrand reflects a maturing ecosystem with clearer architectural boundaries. For developers:

  • Real-time operations → Stellar RPC
  • Historical queries → Horizon API
  • Smart contracts → Both (Stellar RPC for invocation, Horizon for indexed history)
  • The transition is designed to be smooth, with backwards compatibility during the migration period. Start updating your endpoints today to take advantage of the unified infrastructure.


    *Ready to use the new Stellar RPC? LumenQuery provides fully managed Stellar RPC with 99.9% uptime, automatic failover, and built-in rate limiting.*