RILoracle — Integration Docs

● XDC Mainnet

Live, multi-source price & data feeds — multi-chain: anchored on the XDC Network and published natively to the XRP Ledger (XLS-47). Chainlink AggregatorV3-compatible, signed payloads, public REST API. Integrate in minutes.

Overview

RILoracle publishes verified feeds two ways:

Every value is the median of multiple independent sources (the same robustness model Chainlink uses), pushed on-chain on a deviation + heartbeat schedule. All amounts use 8 decimals (Chainlink convention): on_chain_value = round(real_value × 1e8).

Network & contracts

ItemValue
NetworkXDC Network — Mainnet (chainId 50)
RPChttps://rpc.ankr.com/xdc · https://erpc.xinfin.network
Core oracle contractloading…
Decimals8 (all feeds)

AggregatorV3 proxy addresses

loading…

Testnet — integrate risk-free (Apothem)

A copy of the oracle runs on XDC Apothem testnet with drop-in AggregatorV3 proxies for the headline pairs. Point your dApp here to test integration without spending real XDC — grab free test XDC from the Apothem faucet. The live JSON map (mainnet + testnet, always current) is at /api/oracle/addresses.

ItemValue
NetworkXDC Apothem testnet (chainId 51)
RPChttps://erpc.apothem.network · https://rpc.apothem.network
Core oracle contract0xeB5C2437E22CD9028FD31e2Efa668c55B75C8aC1
Faucethttps://faucet.apothem.network
Decimals8 (all feeds)

Testnet AggregatorV3 proxies:

PairTestnet proxy address
XDC / USD0xb5e1595a8464299bC7fCfC2750A963972ce0d01f
BTC / USD0xb0c9D091a417726870D086cAF0a0707eC4D04E7d
ETH / USD0x96a7297d8dd8f59a485785044209c443d961b4fb
USD / EUR0xB27D1314067724402748f026B659F4D467439bc8
Gold XAU / USD0xDA9995163286aEeb9e11106b861E5715775925a6
CGO NAV (USD/g)0x191ef525D59A90f522C30a7cc49f2d8C5620fCA2

Quickstart

Fastest path — read XDC/USD off-chain, no key, no wallet:

# every feed, with values, sources, signatures
curl https://riloracle.ripitlabs.com/api/oracle/public

On-chain · AggregatorV3 proxies (drop-in Chainlink)

For the headline feeds (XDC/USD, BTC/USD, ETH/USD, USD/EUR, Gold XAU/USD, CGO NAV, CBOE VIX, Fed Funds Rate, Natural Gas) point any existing Chainlink integration at the proxy address — zero code changes. The live address list (9 proxies) loads above and at /api/oracle/addresses.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

interface AggregatorV3Interface {
  function decimals() external view returns (uint8);
  function latestRoundData() external view returns (
    uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}

contract PriceConsumer {
  // XDC/USD proxy — see address list above
  AggregatorV3Interface public constant feed =
    AggregatorV3Interface(0x…);

  function xdcUsd() external view returns (int256) {
    (, int256 answer,,,) = feed.latestRoundData();
    return answer; // 8 decimals → divide by 1e8
  }
}

On-chain · read ANY feed via the core oracle

Every feed (gold, CGO NAV, FX, commodity, logistics…) is readable from the core oracle by its bytes32 feed id. The feed id is simply the ASCII feed key, right zero-padded to 32 bytes — so bytes32("rwa_cgo_usd") works directly in Solidity.

interface IXDCOracle {
  function latestRoundData(bytes32 feedId) external view returns (
    uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
  function decimals(bytes32 feedId) external view returns (uint8);
}

IXDCOracle constant ORACLE = IXDCOracle(0x…);

// ComTech Gold NAV — USD per gram (1 CGO = 1g fine gold)
function cgoNav() external view returns (int256) {
  (, int256 answer,,,) = ORACLE.latestRoundData(bytes32("rwa_cgo_usd"));
  return answer; // e.g. 13409000000 = $134.09 (8 dp)
}
Feed keys > 31 chars won't fit in bytes32("…") — all current keys fit. The exact bytes32 id for every feed is in the reference table.

On-chain · ethers.js

import { ethers } from "ethers";
const provider = new ethers.JsonRpcProvider("https://rpc.ankr.com/xdc");
const abi = ["function latestRoundData(bytes32) view returns (uint80,int256,uint256,uint256,uint80)"];
const oracle = new ethers.Contract("0x…", abi, provider);

const feedId = ethers.encodeBytes32String("commodity_xau_usd"); // gold XAU/USD
const [, answer] = await oracle.latestRoundData(feedId);
console.log("gold $/oz =", Number(answer) / 1e8);

XRP Ledger · native Price Oracle (XLS-47)

The same feeds publish natively to the XRP Ledger using XRPL's built-in Price Oracle (XLS-47) — not an EVM sidechain or wrapper contract. XRPL apps read them straight off L1 with the get_aggregate_price method: no gas token, no ABI, no API key. The live account + per-feed pair map is always at /api/oracle/addresses under xrpl.

ItemValue
NetworkXRPL Mainnet
StandardXLS-47 native Price Oracle (Oracle ledger objects)
Oracle accountloading…
Public RPChttps://s1.ripple.com:51234 · wss://s1.ripple.com
Layout47 pairs across 5 oracle objects (≤10 each), addressed by oracle_document_id
Each feed is a base_asset/quote_asset pair under a fixed oracle_document_id. 3-character symbols (BTC, USD, XAU) are standard XRPL currency codes; longer ones (SOFR, UST10Y) are 160-bit hex codes — but you don't compute any of it: the exact base, quote and oracleDocumentId for every feed are in /api/oracle/addresses → xrpl.pairs. XRPL prices are unsigned, so the two spread feeds that can go negative aren't published on XRPL.

Read a feed — Python (xrpl-py)

from xrpl.clients import JsonRpcClient
from xrpl.models.requests import GetAggregatePrice

client = JsonRpcClient("https://s1.ripple.com:51234")
ORACLE = "rJatUN1GtyqvdtG46QuPYftkUWu1wifcxc"  # RILoracle

# BTC/USD lives in oracle_document_id 0 (see /api/oracle/addresses → xrpl.pairs)
resp = client.request(GetAggregatePrice(
    base_asset="BTC", quote_asset="USD",
    oracles=[{"account": ORACLE, "oracle_document_id": 0}]))
print(resp.result["entire_set"]["mean"])   # live BTC/USD off the ledger

Read a feed — JavaScript (xrpl.js)

import { Client } from "xrpl";
const client = new Client("wss://s1.ripple.com");
await client.connect();
const ORACLE = "rJatUN1GtyqvdtG46QuPYftkUWu1wifcxc";

const res = await client.request({
  command: "get_aggregate_price",
  base_asset: "BTC", quote_asset: "USD",
  oracles: [{ account: ORACLE, oracle_document_id: 0 }]
});
console.log(res.result.entire_set.mean);  // live BTC/USD
await client.disconnect();
Other pairs work the same — swap base_asset/quote_asset and use that feed's oracleDocumentId from the addresses map. e.g. gold = XAU/USD, SOFR & the Treasury curve use hex codes you can copy straight from xrpl.pairs.

Off-chain · REST API

Base URL https://riloracle.ripitlabs.com. No auth. JSON. Rate-limited (see below).

EndpointReturns
GET /api/oracle/publicAll feeds: value, unit, source, real flag, decimals, answer_raw, signature, SHA-256 hash + on-chain meta (contract, proxies)
GET /api/oracle/feedsFeed list with metadata
GET /api/oracle/feeds/{key}A single feed
GET /api/oracle/feeds/{key}/onchainThe exact on-chain value (latestRoundData) any contract sees
GET /api/oracle/onchain/statusContract address, operator balance, last-push status
GET /api/oracle/pubkeyEd25519 public key + how to verify signatures
GET /api/oracle/methodologyPer-feed source list & aggregation method
GET /api/oracle/historyHistorical values
GET /api/oracle/healthOracle uptime / freshness
GET /api/oracle/iso20022/{key}ISO 20022 proof as camt.052 (BankToCustomerAccountReport) XML
GET /api/oracle/iso20022/{key}?type=camt.053ISO 20022 proof as camt.053 (BankToCustomerStatement) XML

JavaScript

const r = await fetch("https://riloracle.ripitlabs.com/api/oracle/public").then(r => r.json());
console.log(r.feeds.commodity_xau_usd.value); // gold $/oz
console.log(r.feeds.rwa_cgo_usd.value);       // CGO NAV $/g

Python

import requests
d = requests.get("https://riloracle.ripitlabs.com/api/oracle/public").json()
gold = d["feeds"]["commodity_xau_usd"]
print(gold["value"], gold["source"], gold["sources"], "sources")

Off-chain · signature verification

Each feed in /public is signed with Ed25519. Reconstruct the message and verify against the published public key (signing.pubkey or /api/oracle/pubkey):

# message format
v1:{feed_key}:{answer_raw}:{decimals}:{signed_at}
from nacl.signing import VerifyKey
import requests, binascii

d   = requests.get("https://riloracle.ripitlabs.com/api/oracle/public").json()
pk  = VerifyKey(binascii.unhexlify(d["signing"]["pubkey"]))
f   = d["feeds"]["rwa_cgo_usd"]
msg = f"v1:rwa_cgo_usd:{f['answer_raw']}:{f['decimals']}:{f['signed_at']}".encode()
pk.verify(msg, binascii.unhexlify(f["signature"]))  # raises if tampered
print("verified ✓")

ISO 20022 · bank-native proof messages

Every proof is also served as a genuine ISO 20022 message — the standard banks and market infrastructures run on — so a counterparty can ingest a Proof-of-Reserve / Proof-of-Record straight into their existing pipeline and independently verify it. The attested value becomes the reported Balance/Amt; the Ed25519 signature, SHA-256 hash and on-chain anchor (contract, chainId, Merkle root) travel in the report fields.

MessageISO 20022 typeLive sample
Intraday reportcamt.052.001.08/api/oracle/iso20022/rwa_cgo_usd
End-of-day statementcamt.053.001.08…/iso20022/rwa_cgo_usd?type=camt.053
# pull a Proof-of-Reserve as an ISO 20022 camt.052 message
curl https://riloracle.ripitlabs.com/api/oracle/iso20022/rwa_cgo_usd
<!-- camt.052.001.08 (abbreviated) -->
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.052.001.08">
 <BkToCstmrAcctRpt><Rpt>
  <Acct><Id><Othr><Id>rwa_cgo_usd</Id></Othr></Id><Ccy>USD</Ccy></Acct>
  <Bal><Amt Ccy="USD">133.24</Amt><CdtDbtInd>CRDT</CdtDbtInd></Bal>
  <AddtlRptInf>… algo=ed25519 signature=… sha256=… contract=0x17e46C96… merkleRoot=… …</AddtlRptInf>
 </Rpt></BkToCstmrAcctRpt>
</Document>
Real ISO 20022 message output (camt.052 / camt.053) — correct namespace & structure, parseable by any ISO 20022 tool. XDC is an ISO 20022-aligned network; this makes the oracle's proofs directly consumable by ISO 20022 systems.

Feed reference

Live feeds and their on-chain ids. ● LIVE = real multi-source market data.

FeedKeybytes32 feed idDecValueStatus
loading live feeds…

Rate limits & support

RILoracle by Rip It Labs · built on XDC Network.