QXMP Oracle System

QXMP Oracle
Integration Guide

Fetch real-world asset data via the public REST API or directly from on-chain smart contracts. Managing $1.1 trillion in tokenized assets with verifiable proofs.

Public REST API • No Auth Required • JavaScript / Python / curl Examples • On-Chain Proof-of-Reserve

Custom Oracle Infrastructure

QXMP has built a custom oracle system (not RedStone or Chainlink) for providing real-world asset valuations on-chain. Unlike traditional oracles that rely on third-party data providers, QXMP maintains full sovereignty over data verification, timing, and quality assurance.

Recommended: Use the REST API

The QXMP Oracle API (api.qxmp.ai) reads from the on-chain smart contracts and enriches raw data with human-readable names, types, jurisdictions, and proof-of-reserve validation status. You do NOT need to interact with the smart contracts directly — the API does this for you. See the REST API section below.

Design Philosophy

Data Sovereignty: Complete control over data sources, validation logic, and submission timing

Cryptographic Verification: Every data point cryptographically signed and verifiable on-chain via ECDSA

Complete Auditability: Full historical trail of all valuations with immutable timestamps

8 Decimal Precision

USD values stored with 8 decimal places for accuracy

EIP-191 Standard

Ethereum-standard signature format for compatibility

Staleness Protection

24-hour default freshness requirement prevents replay attacks

Soft Delete Support

Data preservation for regulatory compliance

Dynamic Fields

Unlimited metadata fields per asset with schema versioning

12 Assets Live

Managing $1.1 trillion across mining & resource projects

QXMP Oracle REST API

The QXMP Oracle REST API is a public, unauthenticated JSON API that provides enriched RWA asset data sourced from three verified smart contracts on the QELT blockchain. This is the recommended integration method for most developers.

Base URLhttps://api.qxmp.ai/api/v1/rwa
ProtocolHTTPS (JSON REST)
AuthenticationNone required — Public API
Rate LimitingReturns HTTP 429 with Retry-After header when exceeded
CORSEnabled — call directly from any browser
Response FormatAll responses wrapped in { success: true, data: { ... } }

Architecture Overview

┌──────────────┐     HTTPS      ┌──────────────────────┐     reads from     ┌────────────────────┐
│  Your App /  │ ──────────────▶│  QXMP Oracle REST API │ ◀───────────────── │  QELT Blockchain   │
│  Any Client  │   (JSON REST)  │  api.qxmp.ai          │                    │  (EVM L1)          │
└──────────────┘                └──────────────────────┘                    └────────────────────┘
                                        │
                                        │ reads from 3 smart contracts:
                                        │  • QXMPDynamicRegistryV2
                                        │  • QXMPProofOfReserveV3
                                        │  • QXMPOracleController
                                        └──────────────────────────────────────────┘

API Endpoints

GET/health

Check if the Oracle API and blockchain connection are healthy.

GET https://api.qxmp.ai/api/v1/rwa/health

Response:
{
  "success": true,
  "status": "healthy",
  "blockchain": { ... },
  "timestamp": "2026-02-11T10:00:00.000Z"
}
GET/assetsMain Endpoint

Fetch all RWA assets with valuations, proof status, and on-chain data. This is the primary endpoint most developers need.

ParamTypeDefaultDescription
pagenumber1Page number
limitnumber50Items per page (max: 100)
GET https://api.qxmp.ai/api/v1/rwa/assets?page=1&limit=100

Response:
{
  "success": true,
  "data": {
    "assets": [
      {
        "assetCode": "QXMP:RHENO-JORC-ZA",
        "name": "Rhenosterspruit / Syferfontein Mining Project",
        "type": "Rare Earth Elements",
        "jurisdiction": "ZA",
        "valueUSD": "113989838841.85",
        "status": "registered",
        "holder": "0x...",
        "assetCodeHash": "0x...",
        "txHash": "0x...",
        "registeredAt": "2025-06-15T...",
        "updatedAt": "2026-02-10T...",
        "onChain": {
          "registryValue": "113989838841.85",
          "holder": "0x...",
          "registeredAt": "2025-06-15T...",
          "lastUpdated": "2026-02-10T..."
        },
        "latestProof": {
          "valueUSD": "113989838841.85",
          "timestamp": "2026-02-10T12:00:00.000Z",
          "ageHours": "23.5",
          "isFresh": true,
          "submitter": "0x..."
        },
        "proofHistory": [
          {
            "valueUSD": "113989838841.85",
            "timestamp": "2026-02-10T12:00:00.000Z"
          }
        ]
      }
    ],
    "pagination": { "page": 1, "limit": 100, "total": 12, "totalPages": 1 },
    "summary": { "count": 12, "totalValue": "1090958787645.94", "currency": "USD" }
  }
}
Key Fields per Asset
FieldTypeDescription
assetCodestringUnique identifier, e.g. "QXMP:RHENO-JORC-ZA"
namestringHuman-readable name of the asset
typestringCategory: "Gold", "Diamond", "Rare Earth Elements", "Heavy Mineral Sands", "Nickel and Cobalt"
jurisdictionstringCountry code: "ZA", "NA", "MZ", "LR", "AU"
valueUSDstringUSD valuation — parse with parseFloat()
latestProofobjectMost recent oracle proof-of-reserve submission
latestProof.isFreshbooleantrue if proof is less than 24 hours old
latestProof.ageHoursstringHours since proof was submitted
proofHistoryarrayHistorical proof submissions
GET/assets/{assetCode}

Get full details for a single asset including complete on-chain data and proof history.

GET https://api.qxmp.ai/api/v1/rwa/assets/QXMP:RHENO-JORC-ZA

Returns the same asset object shape as above, with full onChain data and proofHistory.
GET/stats

Get portfolio-level statistics: total value, average value, breakdowns by asset type and jurisdiction.

GET https://api.qxmp.ai/api/v1/rwa/stats

Response:
{
  "success": true,
  "data": {
    "totalAssets": 12,
    "totalValue": "1090958787645.94",
    "averageValue": "90913232303.83",
    "currency": "USD",
    "byType": [
      { "type": "Rare Earth Elements", "count": 3, "value": "504758269067.14", "percentage": "46.27" },
      { "type": "Gold", "count": 2, "value": "198234567890.12", "percentage": "18.17" }
    ],
    "byJurisdiction": [
      { "jurisdiction": "ZA", "count": 8, "value": "783302841350.92", "percentage": "71.80" },
      { "jurisdiction": "NA", "count": 2, "value": "156789012345.67", "percentage": "14.37" }
    ]
  }
}

Fetch RWA Data — Code Examples

Copy-paste examples to start fetching RWA asset data immediately. No authentication, no API keys, no setup.

JavaScript / TypeScript

Works in any browser, Node.js, React, Next.js, Vue, or any JavaScript framework.

// Base URL for the QXMP Oracle API
const API_BASE = 'https://api.qxmp.ai/api/v1/rwa';

// ─── Get all RWA assets ───────────────────────────────
async function getAllAssets(page = 1, limit = 100) {
  const response = await fetch(
    `${API_BASE}/assets?page=${page}&limit=${limit}`
  );
  const result = await response.json();

  if (!result.success) {
    throw new Error(result.error || 'API request failed');
  }

  // Parse string values to numbers for display
  const assets = result.data.assets.map(asset => ({
    ...asset,
    valueUSD: parseFloat(asset.valueUSD),
    registeredAt: new Date(asset.registeredAt),
    updatedAt: new Date(asset.updatedAt),
    latestProof: asset.latestProof ? {
      ...asset.latestProof,
      valueUSD: parseFloat(asset.latestProof.valueUSD),
      timestamp: new Date(asset.latestProof.timestamp),
      ageHours: parseFloat(asset.latestProof.ageHours)
    } : null
  }));

  return {
    assets,
    pagination: result.data.pagination,
    summary: {
      count: result.data.summary.count,
      totalValue: parseFloat(result.data.summary.totalValue),
      currency: result.data.summary.currency
    }
  };
}

// ─── Get portfolio statistics ─────────────────────────
async function getPortfolioStats() {
  const response = await fetch(`${API_BASE}/stats`);
  const result = await response.json();

  if (!result.success) {
    throw new Error(result.error || 'API request failed');
  }

  return {
    totalAssets: result.data.totalAssets,
    totalValue: parseFloat(result.data.totalValue),
    averageValue: parseFloat(result.data.averageValue),
    currency: result.data.currency,
    byType: result.data.byType.map(item => ({
      type: item.type,
      count: item.count,
      value: parseFloat(item.value),
      percentage: parseFloat(item.percentage)
    })),
    byJurisdiction: result.data.byJurisdiction.map(item => ({
      jurisdiction: item.jurisdiction,
      count: item.count,
      value: parseFloat(item.value),
      percentage: parseFloat(item.percentage)
    }))
  };
}

// ─── Get a single asset with full details ─────────────
async function getAsset(assetCode) {
  const response = await fetch(
    `${API_BASE}/assets/${assetCode}`
  );
  const result = await response.json();

  if (!result.success) {
    throw new Error(result.error || 'API request failed');
  }

  return result.data;
}

// ─── Check API health ─────────────────────────────────
async function checkHealth() {
  const response = await fetch(`${API_BASE}/health`);
  return await response.json();
}

// ─── Example usage ────────────────────────────────────
const data = await getAllAssets();
console.log(`Total: ${data.summary.count} assets worth $${data.summary.totalValue.toLocaleString()}`);

for (const asset of data.assets) {
  const proof = asset.latestProof?.isFresh ? '✅ Fresh' : '⚠️ Stale';
  console.log(`  ${asset.assetCode}: $${asset.valueUSD.toLocaleString()} [${proof}]`);
}

curl (Quick Testing)

Test the API from your terminal in seconds.

# Get all assets
curl -s "https://api.qxmp.ai/api/v1/rwa/assets?page=1&limit=100" | jq .

# Get portfolio stats
curl -s "https://api.qxmp.ai/api/v1/rwa/stats" | jq .

# Get a specific asset by code
curl -s "https://api.qxmp.ai/api/v1/rwa/assets/QXMP:RHENO-JORC-ZA" | jq .

# Health check
curl -s "https://api.qxmp.ai/api/v1/rwa/health" | jq .

Python

Using the requests library.

import requests

API_BASE = "https://api.qxmp.ai/api/v1/rwa"

def get_all_assets(page=1, limit=100):
    response = requests.get(f"{API_BASE}/assets", params={"page": page, "limit": limit})
    data = response.json()
    if not data.get("success"):
        raise Exception(data.get("error", "API request failed"))
    return data["data"]

def get_portfolio_stats():
    response = requests.get(f"{API_BASE}/stats")
    data = response.json()
    if not data.get("success"):
        raise Exception(data.get("error", "API request failed"))
    return data["data"]

def get_asset(asset_code):
    response = requests.get(f"{API_BASE}/assets/{asset_code}")
    data = response.json()
    if not data.get("success"):
        raise Exception(data.get("error", "API request failed"))
    return data["data"]

# ─── Example usage ─────────────────────────────────────
assets_data = get_all_assets()
print(f"Total assets: {assets_data['summary']['count']}")
print(f"Total value: ${float(assets_data['summary']['totalValue']):,.2f}")

for asset in assets_data["assets"]:
    proof_status = "✅ Fresh" if asset.get("latestProof", {}).get("isFresh") else "⚠️ Stale/None"
    print(f"  {asset['assetCode']}: ${float(asset['valueUSD']):,.2f} [{proof_status}]")

Quick Start Summary

GET /assets?page=1&limit=100 — All assets with valuations, proof status, and on-chain data

GET /stats — Portfolio-level statistics (total value, breakdowns by type/jurisdiction)

GET /assets/{assetCode} — Full detail for a single asset including proof history

GET /health — API and blockchain connection health status

No authentication required. All responses are JSON. Parse valueUSD fields with parseFloat() as they come as strings.

Rate Limiting & Caching

Rate Limiting

  • API returns HTTP 429 when rate limited
  • Retry-After header contains wait time in seconds
  • Implement exponential backoff with 3 retries
  • Deduplicate in-flight requests to the same endpoint

Recommended Caching

  • Cache responses for at least 60 seconds
  • Oracle proofs update ~once per day, so data is stable
  • A 2–5 minute cache is ideal for display purposes
  • Auto-refresh every 60s for live dashboards

Example: Retry with Backoff (JavaScript)

async function fetchWithRetry(url, retries = 3) {
  for (let i = 0; i < retries; i++) {
    const response = await fetch(url);

    if (response.status === 429) {
      const retryAfter = parseInt(response.headers.get('Retry-After') || '5');
      console.warn(`Rate limited. Retrying in ${retryAfter}s...`);
      await new Promise(r => setTimeout(r, retryAfter * 1000));
      continue;
    }

    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    return await response.json();
  }
  throw new Error('Max retries exceeded');
}

Asset Data Reference

Asset Types

TypeDescription
GoldGold mining concessions and reserves
DiamondDiamond mining reserves
Rare Earth ElementsRare earth mining projects
Heavy Mineral SandsHeavy mineral sand operations
Nickel and CobaltNickel and cobalt operations

Jurisdictions

CodeCountry
ZASouth Africa
NANamibia
MZMozambique
LRLiberia
AUAustralia

Proof Freshness

Fresh

isFresh === true — proof is less than 24 hours old

Stale

isFresh === false — proof is older than 24 hours

Age

ageHours — exact hours since proof submission

Smart Contracts (On-Chain)

Three core smart contracts work together to provide secure, verifiable asset pricing data on the QELT blockchain. Deployed on January 12, 2026, by deployer wallet 0xBd6C978C38b0954e1153fB9892f007611726E2B0. The REST API reads from these contracts — most developers won't need to interact with them directly.

QXMPOracleController

Manages authorized signers and verifies oracle signatures using ECDSA cryptography

Signature VerificationSigner ManagementEIP-191 Standard
0xB2a332dE80923134393306808Fc2CFF330de03bAView on Explorer

QXMPProofOfReserveV3

Submits and stores proof submissions with complete audit trail. Owns Registry contract for automatic value updates.

Proof SubmissionAudit TrailOwns Registry
0x6123287acBf0518E0bD7F79eAcAaFa953e10a768View on Explorer

QXMPDynamicRegistryV2

Universal key-value storage for asset data with soft delete support. Schema-less design supports any asset type.

Asset StorageDynamic FieldsSoft Delete
0xd00cD3a986746cf134756464Cb9Eaf024DF110fBView on Explorer

Ownership Architecture

ProofOfReserve V3 owns Registry V2, allowing automatic value updates when new oracle proofs are submitted. The deployer wallet owns ProofOfReserve for administrative operations.

Deployer (0xBd6C...E2B0)
└─► ProofOfReserveV3 (0x6123...B8c)
└─► DynamicRegistryV2 (0xd00c...0fB)

System Architecture

Three-layer architecture ensures maximum security, flexibility, and separation of concerns

1Controller Layer: Signature Verification

OracleController manages authorized signers and validates ECDSA signatures using EIP-191 standard. Configurable staleness thresholds (24h default) and value bounds provide anomaly detection.

verifySignature()

ECDSA validation

addSigner()

Manage signers

isSigner()

Check authorization

Signature Verified

2Proof Layer: Audit Trail & Submission

ProofOfReserveV3 stores oracle-verified proofs with complete audit trails. Each proof includes value, timestamp, block number, and signer address for full transparency. Owns Registry for automatic updates.

submitProofWithSignature()

Store verified proof

getLatestProof()

Query latest data

getProofHistory()

Historical records

Update Registry

3Registry Layer: Asset Storage

DynamicRegistryV2 stores asset metadata with schema-less dynamic fields. Supports ANY asset type - gold, platinum, lithium, uranium, diamonds, and more. Unlimited custom fields per asset.

getAsset()

Core asset data

getAssetFields()

Dynamic metadata

updatePrimaryValue()

Update valuations

Oracle Mechanism

Understanding how asset codes, signatures, and proofs work together

Asset Code Generation

Asset codes use Keccak-256 hashing for deterministic identifiers

// Format: QXMP:{PROJECT}-{STD}-{COUNTRY}
const assetCode = ethers.utils.id(
  'QXMP:ATKA2-NI43-ZA'
);
// Result: 0x4f8b... (bytes32 hash)

Value Encoding

USD values stored with 8 decimal precision

const valueUsd = 125000000.50; // $125M
const encoded = ethers.utils.parseUnits(
  valueUsd.toString(), 8
);
// Result: 12500000050000000

Signature Generation

ECDSA signatures with EIP-191 standard

// 1. Create message hash
const hash = ethers.utils.solidityKeccak256(
  ['bytes32', 'bytes32', 'uint256', 'uint256'],
  [assetCode, dataFeedId, value, timestamp]
);

// 2. Sign with private key
const sig = await signer.signMessage(
  ethers.utils.arrayify(hash)
);

On-Chain Verification

Contract verifies signature and stores proof

// Verify signature
address signer = controller.verifySignature(
  messageHash, signature
);
require(
  controller.isSigner(signer),
  "Invalid signer"
);

// Store proof & update registry

On-Chain Quick Start (Advanced)

Note: Most developers should use the REST API above instead of reading smart contracts directly. The on-chain approach below is for advanced use cases where you need to verify data directly on the blockchain without trusting the API layer.

Integrate with QXMP Oracle smart contracts in 4 steps using ethers.js

1

Install Dependencies

Add ethers.js to your project

npm install ethers@5.7.2
2

Connect to QELT Blockchain

Initialize provider and contract instances

const { ethers } = require('ethers');

// Connect to QELT
const provider = new ethers.providers.JsonRpcProvider(
  'https://mainnet.qelt.ai'
);

// Contract addresses
const REGISTRY = '0xd00cD3a986746cf134756464Cb9Eaf024DF110fB';
const PROOF_OF_RESERVE = '0x6123287acBf0518E0bD7F79eAcAaFa953e10a768';
const CONTROLLER = '0xB2a332dE80923134393306808Fc2CFF330de03bA';
3

Query Asset Data

Read asset information from Registry

// Load Registry contract
const registry = new ethers.Contract(
  REGISTRY,
  REGISTRY_ABI,
  provider
);

// Generate asset code
const assetCode = ethers.utils.id('QXMP:ATKA2-NI43-ZA');

// Get asset data
const asset = await registry.getAsset(assetCode);
console.log('Name:', asset.assetName);
console.log('Type:', asset.assetType);
console.log('Value:', ethers.utils.formatUnits(asset.primaryValueUsd, 8));
4

Get Latest Proof

Query oracle proofs with timestamps

// Load Proof of Reserve contract
const proofOfReserve = new ethers.Contract(
  PROOF_OF_RESERVE,
  PROOF_OF_RESERVE_ABI,
  provider
);

// Get latest proof
const dataFeedId = ethers.utils.id('QXMP:ATKA2-NI43-ZA-FULL');
const proof = await proofOfReserve.getLatestProof(
  assetCode, 
  dataFeedId
);

console.log('Value:', ethers.utils.formatUnits(proof.value, 8), 'USD');
console.log('Timestamp:', new Date(proof.timestamp * 1000).toISOString());
console.log('Submitter:', proof.submitter);

Network Information

QELT Blockchain
Network Name
770
Chain ID (0x302 hex)
QBFT PoA
Consensus (Hyperledger Besu)
3-Layer
Architecture
24 Hours
Update Frequency
Live
Operational Status
12 Assets
Total Registered
$1.1T
Total Asset Value
450+
Proofs Submitted

Deployed & Operational on QELT Blockchain

All contracts deployed January 12, 2026, and fully operational. Query real asset data and oracle proofs directly from the blockchain.

Security Features

ECDSA Signature Verification

Every proof cryptographically signed using secp256k1 elliptic curve (same as Ethereum wallets). Unforgeability guaranteed without private key access.

  • • EIP-191 compliant signature format
  • • 65-byte signatures (r, s, v components)
  • • On-chain ecrecover verification

Staleness Protection

24-hour default freshness requirement prevents replay attacks and ensures data currency. Configurable threshold per deployment.

  • • Automatic timestamp validation
  • • Prevents old proof resubmission
  • • Ensures up-to-date valuations

Immutable Audit Trail

Complete proof history permanently stored on QELT blockchain. No functions to modify or delete existing records - only soft delete for fields.

  • • Block-level precision timestamps
  • • Event logs for off-chain indexing
  • • Transparent transaction history

Access Control

Only authorized signers can submit valid proofs. Multi-level access control with owner-only administrative functions.

  • • Signer whitelist management
  • • Owner-only configuration updates
  • • Public read access for transparency

Registered Assets

Currently managing 12 tokenized mining and resource projects across multiple jurisdictions

Asset CodeNameTypeStandardJurisdiction
ATKA2-NI43-ZAAtka Platinum ProjectPlatinumNI 43-101South Africa
GOLD1-NI43-ZAGold Reserve 1GoldNI 43-101South Africa
LITH3-JORC-AULithium Deposit 3LithiumJORCAustralia
URANIUM9-JORC-NAUranium Deposit 9UraniumJORCNamibia
DIAMOND10-NI43-BWDiamond Mine 10DiamondsNI 43-101Botswana

And 7 additional assets spanning copper, silver, nickel, zinc, cobalt, and rare earth elements

Why QXMP Oracle?

Data Sovereignty

QXMP maintains complete control over data sources, validation logic, and submission timing. No dependency on third-party oracle providers like Chainlink or RedStone.

Cryptographic Proofs

Every data point cryptographically signed with ECDSA and verified on-chain. Immutable audit trail with block-level precision for regulatory compliance.

Universal Asset Support

Schema-less dynamic field system supports ANY asset type with unlimited custom metadata. Perfect for diverse RWA portfolios.

Low Cost & Fast

Deployed on QELT blockchain with ~$0.002 per transaction and 3-second block times. Sub-second proof submission when market conditions change.

Ready to Integrate QXMP Oracle?

Start fetching RWA data in minutes with the public REST API. No authentication required. Or go deeper with direct on-chain smart contract access.