Top 5 Horizon & RPC Use Cases for Financial Apps in 2026
Stellar's combination of Horizon API and Stellar RPC powers some of the most innovative financial applications in the blockchain space. Here are the top five use cases we're seeing in 2026, complete with real API patterns you can implement today.
1. Cross-Border Payments
The original Stellar use case remains one of the strongest. Cross-border payment platforms use Stellar for instant, low-cost international transfers.
How It Works
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Sender │ │ Stellar │ │ Recipient │
│ (USD) │────▶│ Network │────▶│ (EUR) │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
▼ ▼ ▼
On-ramp Path Payment Off-ramp
(Bank→USDC) (USDC→EUR) (EUR→Bank)API Pattern: Path Payment with Best Rate
// Find the best path for a cross-border payment
async function findBestPath(
sourceAsset: Asset,
destAsset: Asset,
amount: string
) {
// Use Horizon's path finding endpoint
const response = await fetch(
`${HORIZON_URL}/paths/strict-send?` +
`source_asset_type=${sourceAsset.type}&` +
`source_asset_code=${sourceAsset.code}&` +
`source_asset_issuer=${sourceAsset.issuer}&` +
`destination_assets=${destAsset.code}:${destAsset.issuer}&` +
`source_amount=${amount}`,
{ headers: { 'X-API-Key': API_KEY } }
);
const data = await response.json();
const paths = data._embedded.records;
// Return path with maximum destination amount
return paths.reduce((best, current) =>
parseFloat(current.destination_amount) > parseFloat(best.destination_amount)
? current
: best
);
}
// Execute the path payment
async function executePathPayment(
sender: Keypair,
destination: string,
path: PathResult,
sourceAmount: string
) {
const account = await server.loadAccount(sender.publicKey());
const transaction = new TransactionBuilder(account, {
fee: '100',
networkPassphrase: Networks.PUBLIC,
})
.addOperation(Operation.pathPaymentStrictSend({
sendAsset: path.source_asset,
sendAmount: sourceAmount,
destination,
destAsset: path.destination_asset,
destMin: (parseFloat(path.destination_amount) * 0.99).toFixed(7), // 1% slippage
path: path.path.map(p => new Asset(p.asset_code, p.asset_issuer)),
}))
.setTimeout(30)
.build();
transaction.sign(sender);
return server.submitTransaction(transaction);
}Real-World Example
MoneyGram Access: Uses Stellar for USD↔local currency corridors across 180 countries.
2. Token Issuance & Management
Companies issue tokens on Stellar for loyalty points, securities, stablecoins, and digital collectibles.
How It Works
┌─────────────────────────────────────────────────────┐
│ Issuer Account │
│ • Issues tokens │
│ • Sets authorization flags │
│ • Controls supply │
└─────────────────┬───────────────────────────────────┘
│
┌──────────┴──────────┐
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Distribution│ │ Treasury │
│ Account │ │ Account │
│ (sells/airdrops) │ (holds reserves)
└─────────────┘ └─────────────┘API Pattern: Token Creation & Distribution
// Create a new token with controlled distribution
async function createControlledToken(
issuerKeypair: Keypair,
distributorPublicKey: string,
assetCode: string,
totalSupply: string
) {
// Step 1: Configure issuer account with auth flags
const issuerAccount = await server.loadAccount(issuerKeypair.publicKey());
const configTx = new TransactionBuilder(issuerAccount, {
fee: '100',
networkPassphrase: Networks.PUBLIC,
})
.addOperation(Operation.setOptions({
setFlags: AuthRequiredFlag | AuthRevocableFlag,
}))
.setTimeout(30)
.build();
configTx.sign(issuerKeypair);
await server.submitTransaction(configTx);
// Step 2: Create trustline from distributor to issuer
// (Distributor must do this separately)
// Step 3: Send initial supply to distributor
const asset = new Asset(assetCode, issuerKeypair.publicKey());
const mintTx = new TransactionBuilder(
await server.loadAccount(issuerKeypair.publicKey()),
{ fee: '100', networkPassphrase: Networks.PUBLIC }
)
.addOperation(Operation.payment({
destination: distributorPublicKey,
asset,
amount: totalSupply,
}))
.setTimeout(30)
.build();
mintTx.sign(issuerKeypair);
return server.submitTransaction(mintTx);
}
// Monitor token holders using Horizon
async function getTokenHolders(assetCode: string, issuer: string) {
let holders = [];
let cursor = '';
while (true) {
const response = await fetch(
`${HORIZON_URL}/accounts?` +
`asset=${assetCode}:${issuer}&` +
`limit=200&cursor=${cursor}`,
{ headers: { 'X-API-Key': API_KEY } }
);
const data = await response.json();
const accounts = data._embedded.records;
holders = holders.concat(accounts.map(acc => ({
account: acc.id,
balance: acc.balances.find(
b => b.asset_code === assetCode && b.asset_issuer === issuer
)?.balance || '0',
})));
if (accounts.length < 200) break;
cursor = accounts[accounts.length - 1].paging_token;
}
return holders.sort((a, b) =>
parseFloat(b.balance) - parseFloat(a.balance)
);
}Real-World Example
Circle USDC: Issues USDC natively on Stellar with full reserve backing.
3. Decentralized Exchange (DEX) Integration
Stellar's built-in DEX enables peer-to-peer trading without smart contracts.
How It Works
┌─────────────────────────────────┐
│ Stellar Order Book │
│ ┌─────────────────────────┐ │
│ │ XLM/USDC │ │
│ │ Bids Asks │ │
│ │ 0.099 | | 0.101 │ │
│ │ 0.098 | | 0.102 │ │
│ │ 0.097 | | 0.103 │ │
│ └─────────────────────────┘ │
└─────────────────────────────────┘
▲ │
│ ▼
┌──────┴──────┐ ┌────────────┐
│ Manage Offer│ │ Path Pay │
│ (Makers) │ │ (Takers) │
└─────────────┘ └────────────┘API Pattern: Order Book Trading
// Fetch orderbook for trading pair
async function getOrderbook(
baseAsset: Asset,
counterAsset: Asset
) {
const response = await fetch(
`${HORIZON_URL}/order_book?` +
`selling_asset_type=${baseAsset.isNative() ? 'native' : 'credit_alphanum4'}&` +
(baseAsset.isNative() ? '' :
`selling_asset_code=${baseAsset.code}&selling_asset_issuer=${baseAsset.issuer}&`) +
`buying_asset_type=${counterAsset.isNative() ? 'native' : 'credit_alphanum4'}&` +
(counterAsset.isNative() ? '' :
`buying_asset_code=${counterAsset.code}&buying_asset_issuer=${counterAsset.issuer}`),
{ headers: { 'X-API-Key': API_KEY } }
);
const data = await response.json();
return {
bids: data.bids.map(b => ({
price: b.price,
amount: b.amount,
})),
asks: data.asks.map(a => ({
price: a.price,
amount: a.amount,
})),
spread: data.asks[0] && data.bids[0]
? ((parseFloat(data.asks[0].price) - parseFloat(data.bids[0].price)) /
parseFloat(data.bids[0].price) * 100).toFixed(2) + '%'
: 'N/A',
};
}
// Place a limit order
async function placeLimitOrder(
trader: Keypair,
selling: Asset,
buying: Asset,
amount: string,
price: string,
offerId: string = '0' // '0' for new order
) {
const account = await server.loadAccount(trader.publicKey());
const transaction = new TransactionBuilder(account, {
fee: '100',
networkPassphrase: Networks.PUBLIC,
})
.addOperation(Operation.manageSellOffer({
selling,
buying,
amount,
price,
offerId,
}))
.setTimeout(30)
.build();
transaction.sign(trader);
return server.submitTransaction(transaction);
}
// Stream trades for real-time updates
function streamTrades(
baseAsset: Asset,
counterAsset: Asset,
onTrade: (trade: Trade) => void
) {
const url = new URL(`${HORIZON_URL}/trades`);
url.searchParams.set('base_asset_type', baseAsset.isNative() ? 'native' : 'credit_alphanum4');
if (!baseAsset.isNative()) {
url.searchParams.set('base_asset_code', baseAsset.code);
url.searchParams.set('base_asset_issuer', baseAsset.issuer);
}
// ... counter asset params
url.searchParams.set('cursor', 'now');
const eventSource = new EventSource(url.toString());
eventSource.onmessage = (event) => {
onTrade(JSON.parse(event.data));
};
return () => eventSource.close();
}Real-World Example
StellarX & Lumenswap: DEX interfaces built entirely on Stellar's native orderbook.
4. Real-Time Transaction Monitoring
Financial institutions monitor Stellar for compliance, fraud detection, and treasury management.
How It Works
┌─────────────────────────────────────────────────────────┐
│ Monitoring System │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ Horizon SSE │ │ Rule Engine │ │ Alert Dashboard │ │
│ │ (Stream) │──│ (Evaluate) │──│ (Notify) │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
│ │ │ │
│ │ Real-time │ Alerts │
│ │ transactions ▼ │
│ │ ┌─────────────────┐ │
│ └──────────────────────────▶│ Compliance │ │
│ │ Team / API │ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘API Pattern: Compliance Monitoring System
// Real-time transaction monitoring with rules
interface MonitoringRule {
id: string;
name: string;
evaluate: (tx: Transaction, ops: Operation[]) => Alert | null;
}
interface Alert {
ruleId: string;
severity: 'low' | 'medium' | 'high' | 'critical';
transaction: string;
details: Record<string, any>;
}
const rules: MonitoringRule[] = [
{
id: 'large-payment',
name: 'Large Payment Detection',
evaluate: (tx, ops) => {
const payments = ops.filter(op => op.type === 'payment');
for (const payment of payments) {
const amount = parseFloat(payment.amount);
if (payment.asset_type === 'native' && amount > 100000) {
return {
ruleId: 'large-payment',
severity: 'high',
transaction: tx.hash,
details: {
amount,
from: tx.source_account,
to: payment.to,
},
};
}
}
return null;
},
},
{
id: 'new-trustline',
name: 'Trustline Addition',
evaluate: (tx, ops) => {
const trustlines = ops.filter(op => op.type === 'change_trust');
if (trustlines.length > 0) {
return {
ruleId: 'new-trustline',
severity: 'low',
transaction: tx.hash,
details: {
assets: trustlines.map(t => `${t.asset_code}:${t.asset_issuer}`),
},
};
}
return null;
},
},
];
// Start monitoring
async function startMonitoring(
accounts: string[],
onAlert: (alert: Alert) => void
) {
for (const accountId of accounts) {
const url = `${HORIZON_URL}/accounts/${accountId}/transactions?cursor=now`;
const eventSource = new EventSource(url);
eventSource.onmessage = async (event) => {
const tx = JSON.parse(event.data);
// Fetch operations for this transaction
const opsResponse = await fetch(
`${HORIZON_URL}/transactions/${tx.hash}/operations`,
{ headers: { 'X-API-Key': API_KEY } }
);
const opsData = await opsResponse.json();
const operations = opsData._embedded.records;
// Evaluate all rules
for (const rule of rules) {
const alert = rule.evaluate(tx, operations);
if (alert) {
onAlert(alert);
}
}
};
}
}
// Usage
startMonitoring(
['GA...TREASURY', 'GA...OPERATIONS'],
(alert) => {
console.log(`[${alert.severity.toUpperCase()}] ${alert.ruleId}`);
// Send to Slack, email, database, etc.
}
);Real-World Example
Chainalysis & Elliptic: Blockchain analytics firms monitor Stellar for compliance.
5. Smart Contract Management (Soroban)
DeFi protocols and automated financial services use Soroban smart contracts.
How It Works
┌─────────────────────────────────────────────────────────┐
│ DeFi Protocol │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ Frontend │ │ Stellar │ │ Contract │ │
│ │ (React) │──│ RPC │──│ (Soroban) │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
│ │ │ │ │
│ │ User │ Simulate + │ State │
│ │ Actions │ Submit │ Changes │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Horizon (Historical) │ │
│ │ • Transaction history │ │
│ │ • Event indexing │ │
│ │ • Analytics │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘API Pattern: DeFi Protocol Integration
// Interact with a lending protocol smart contract
const LENDING_CONTRACT = 'CDLZFC...';
interface LendingPosition {
deposited: bigint;
borrowed: bigint;
collateralRatio: number;
}
// Read current position from contract state
async function getPosition(accountId: string): Promise<LendingPosition> {
const response = await fetch(STELLAR_RPC_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': API_KEY },
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'getLedgerEntries',
params: {
keys: [createContractDataKey(LENDING_CONTRACT, 'Position', accountId)],
},
}),
});
const { result } = await response.json();
const entry = result.entries[0];
if (!entry) {
return { deposited: 0n, borrowed: 0n, collateralRatio: 0 };
}
// Parse contract state
const data = xdr.LedgerEntryData.fromXDR(entry.xdr, 'base64');
const contractData = data.contractData();
return parsePositionData(contractData.val());
}
// Deposit collateral
async function deposit(
user: Keypair,
amount: string
): Promise<TransactionResult> {
const contract = new Contract(LENDING_CONTRACT);
// Build the invocation
const operation = contract.call(
'deposit',
nativeToScVal(Address.fromString(user.publicKey())),
nativeToScVal(BigInt(parseFloat(amount) * 10_000_000), { type: 'i128' })
);
// Get account and build transaction
const account = await server.loadAccount(user.publicKey());
const transaction = new TransactionBuilder(account, {
fee: '1000000',
networkPassphrase: Networks.PUBLIC,
})
.addOperation(operation)
.setTimeout(30)
.build();
// Simulate
const simResponse = await fetch(STELLAR_RPC_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': API_KEY },
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'simulateTransaction',
params: { transaction: transaction.toXDR() },
}),
});
const { result: simulation } = await simResponse.json();
if (simulation.error) {
throw new Error(`Simulation failed: ${simulation.error}`);
}
// Prepare and sign
const prepared = SorobanRpc.assembleTransaction(transaction, simulation);
prepared.sign(user);
// Submit
const submitResponse = await fetch(STELLAR_RPC_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': API_KEY },
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'sendTransaction',
params: { transaction: prepared.toXDR() },
}),
});
return submitResponse.json();
}
// Monitor protocol events
async function getProtocolEvents(fromLedger: number) {
const response = await fetch(STELLAR_RPC_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': API_KEY },
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'getEvents',
params: {
startLedger: fromLedger,
filters: [{
type: 'contract',
contractIds: [LENDING_CONTRACT],
}],
},
}),
});
const { result } = await response.json();
return result.events.map(event => ({
ledger: event.ledger,
type: parseEventType(event.topic),
data: parseEventData(event.value),
}));
}Real-World Example
Blend Protocol: Lending and borrowing protocol built on Soroban.
Putting It All Together
The most powerful financial applications combine multiple use cases:
// Example: Remittance platform combining multiple patterns
class RemittancePlatform {
// Use Case 1: Cross-border payments
async sendRemittance(from: User, to: User, amount: Money) {
const path = await this.findBestPath(from.currency, to.currency, amount);
return this.executePathPayment(from, to, path);
}
// Use Case 2: Token management (stablecoin)
async issueLocalCurrency(user: User, amount: string) {
return this.mintToken(user, this.localStablecoin, amount);
}
// Use Case 3: DEX for liquidity
async provideLiquidity(asset: Asset, amount: string) {
return this.placeLimitOrder(this.treasury, asset, XLM, amount);
}
// Use Case 4: Compliance monitoring
async monitorTransactions() {
return this.startMonitoring(this.regulatedAccounts, this.handleAlert);
}
// Use Case 5: Smart contracts for automation
async setupAutomaticConversion(user: User, rules: ConversionRule[]) {
return this.deployConversionContract(user, rules);
}
}Conclusion
Stellar's dual API approach—Horizon for historical data and Stellar RPC for real-time state—enables sophisticated financial applications:
With the right API patterns, you can build financial applications that rival traditional fintech—but with the transparency and efficiency of blockchain.
*Building financial applications on Stellar? LumenQuery provides the reliable API infrastructure your fintech needs—Horizon and Stellar RPC with 99.9% uptime.*