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:
The New Model:
What SDF Says
According to the Stellar roadmap, the unification aims to:
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 Method | New Method | Purpose |
|---|---|---|
| getHealth | getHealth | Server health check |
| getLatestLedger | getLatestLedger | Current ledger info |
| simulateTransaction | simulateTransaction | Tx simulation |
| sendTransaction | sendTransaction | Submit transaction |
| getTransaction | getTransaction | Tx status by hash |
| getLedgerEntries | getLedgerEntries | Read state data |
| getEvents | getEvents | Query 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.io3. Review Method Names
Most methods are unchanged, but verify against the latest documentation for any deprecations.
4. Update SDK Versions
npm update @stellar/stellar-sdkThe 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:
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.*