Overview
The current price sources (Stellar DEX orderbook, CoinGecko, CoinMarketCap) miss prices from Stellar's on-chain AMM liquidity pools. AMM pools often have tighter spreads and are the reference price for assets primarily traded on-chain. A Soroban/Horizon AMM source should be added as a fourth price source.
How Stellar AMMs Work
Stellar supports constant-product AMM pools (similar to Uniswap v2). The current price can be derived from:
price_A_in_B = reserve_B / reserve_A
Horizon exposes pool data at:
GET /liquidity_pools?reserves=XLM,USDC:ISSUER
Implementation
Create src/services/sources/stellarAmm.js:
const { Horizon } = require('@stellar/stellar-sdk');
async function fetchFromAMM(assetCode, issuer, horizonUrl) {
const server = new Horizon.Server(horizonUrl);
const pools = await server
.liquidityPools()
.forAssets(makeAsset(assetCode, issuer), makeAsset('XLM'))
.call();
if (!pools.records.length) return null;
// Find deepest pool (highest total value)
const best = pools.records.sort((a, b) =>
parseFloat(b.total_shares) - parseFloat(a.total_shares)
)[0];
const [reserveA, reserveB] = best.reserves;
const price = parseFloat(reserveB.amount) / parseFloat(reserveA.amount);
return { price_usd: price * XLM_USD_PRICE, source: 'stellar_amm' };
}
Note: XLM_USD_PRICE is fetched from the existing Stellar DEX source.
Acceptance Criteria
Overview
The current price sources (Stellar DEX orderbook, CoinGecko, CoinMarketCap) miss prices from Stellar's on-chain AMM liquidity pools. AMM pools often have tighter spreads and are the reference price for assets primarily traded on-chain. A Soroban/Horizon AMM source should be added as a fourth price source.
How Stellar AMMs Work
Stellar supports constant-product AMM pools (similar to Uniswap v2). The current price can be derived from:
Horizon exposes pool data at:
GET /liquidity_pools?reserves=XLM,USDC:ISSUERImplementation
Create
src/services/sources/stellarAmm.js:Note:
XLM_USD_PRICEis fetched from the existing Stellar DEX source.Acceptance Criteria
stellarAmm.jssource created and registered inpriceOracle.jsnullif no AMM pool exists for the pairfetchFromAllSourcesarray