Orakel-Dokumentation
Signierte Devisen- und Edelmetallkurse, die Ihre Smart Contracts on-chain verifizieren. Überblick: Oracle-Seite · maschinenlesbar: /v1/oracle/feeds, /v1/oracle/catalog.
1. Wie es funktioniert
- Ihr Backend fordert einen signierten Bericht an:
GET https://api.marketapi.app/v1/oracle/report?symbols=XAUUSD&chain_id=10(API-Schlüssel mit dem Scoperead:oracle; Abrechnung pro signiertem Bericht). - Ihre Transaktion übergibt Bericht und Signatur an den Verifier-Vertrag, der die EIP-712-Signatur, den Ablauf, die Chain und seinen Circuit Breaker prüft und dann den Kurs speichert.
- In derselben Transaktion liest Ihr Vertrag den Kurs mit einer Aktualitätsanforderung. Dieses Pull-Muster verwendet immer den aktuellen Kurs.
Über die API angeforderte Kurse werden außerdem von Zeit zu Zeit automatisch on-chain übertragen, aber verlassen Sie sich nie ohne Aktualitätsprüfung auf einen gespeicherten Kurs.
2. Netzwerke und Verträge
| Netzwerk | Chain-ID | Verifier-Vertrag |
|---|---|---|
| Optimism | 10 | 0xaeF7f701acFB42267015D3F593ce17CF536Afd6B · Explorer |
| Optimism Sepolia Testnet | 11155420 | 0xBBf36E7Cd75494f28E02C5698EaD35fF4960a943 · Explorer |
Signer-Adresse: 0x83fa2d8836525251FAd214A78A72038D0864f877. Testnets dienen zum kostenlosen Testen ohne Dienstgarantien.
3. Feeds
Jeder Feed hat eine dauerhafte ID: feedId = keccak256(symbol). Kurse verwenden 8 Dezimalstellen.
| Symbol | feedId |
|---|---|
AUDUSD | 0x5577fa17b1be8ae0f1517fe1864ea534d6992f3721000cdb6585b11e7046d5ec |
EURGBP | 0xeaff3420d70d388655273db9b4f3000962445a6f0ea23ec1f04d843e4dbae4b0 |
EURUSD | 0x0730076c3c0f5da594eb635c5d5a22116233bdb2a9c2977279cc348b8b8ce917 |
GBPUSD | 0xd30842147b60fe333c2700bcae5eee6815b8529847955d19522858806bca8217 |
IEF | 0x309dab183458dd939568dca0d68bea45d34aa25d31fa47fc5f12030e8f227f4e |
OILCash# | 0xe21b90a237aa0663c02092eca221a0098c6c477054a61d05ecd3692f6631f6ff |
SHY | 0x78f1083af8e72ddefc2e66fad95680c38a953b3136f413c61ab40f99b72991bc |
SPY | 0xcea23e8f56b5ac447ac08d57e0808e35f468a65f29bb659b3d48934481e7c67a |
TLT | 0x4abd434857e07567d49487ccf888348e55d5cfc15498c09a9dbcba2820e40ee4 |
USDCAD | 0xa36f6cf3195abb4e93bf276660acee423f78878e6cfdbad0eab36e455afca97e |
USDCHF | 0xd85af9ebd6fec6b317a7ac07f6d6455c4fc915cc8e1cfe19471faca002582907 |
USDJPY | 0x3d6c40e9d821c10e442cb3fc6cb1c589ffd8b906e734a1ab3b3f7d213ac395d6 |
USDSGD | 0x8a1375bd16e33aff9be7037f83e076defe9df6efea6d39a51d0b08f17ac9bc6d |
XAGUSD | 0x67107df7f0e95594d9bf8ad8840bbb2ff95617123c227e10aab4d161dd6959b6 |
XAUUSD | 0xe21c86d8b6a127bfef214d88fdb0c279e55d27dd8c443733e46c8d3de3c98cd6 |
4. Der signierte Bericht
EIP-712-Domain: Name MarketAPI Oracle, Version 2, die Chain-ID und die Verifier-Adresse. Typ:
PriceReport(bytes32 feedId,int256 price,uint64 timestamp,uint64 validUntil,uint8 marketStatus,uint32 spreadBps)
- price: Mittelkurs mit 8 Dezimalstellen.
- timestamp: Zeitpunkt des Kurses (UTC-Sekunden); validUntil: Der Bericht läuft nach etwa einer Minute ab.
- marketStatus: 1 OPEN, 2 CLOSED (offizieller letzter Kurs, z. B. am Wochenende), 3 HALTED.
- spreadBps: Geld-Brief-Spanne in Basispunkten; bei mehreren Brokern spiegelt sie auch wider, wie weit diese auseinanderliegen.
Die API-Antwort enthält report (ABI-codiert) und signature (65 Byte): genau die beiden Argumente von submit.
5. Vertragsfunktionen
submit(PriceReport r, bytes sig) returns (bool): verifizieren und speichern; wird ignoriert, wenn ein gleicher oder neuerer Kurs gespeichert ist.submitBatch(PriceReport[] rs, bytes[] sigs): mehrere Feeds in einer Transaktion; ungültige Einträge werden übersprungen.getPrice(bytes32 feedId): letzter gespeicherter Kurs und Zeitstempel; bricht ab (revert), solange ein Feed noch keinen Kurs hat.getPriceNoOlderThan(bytes32 feedId, uint256 maxAge): bricht ab, außer der Markt ist OPEN und der Kurs frisch genug. Verwenden Sie dies für Handelsaktionen.
Jeder Feed hat einen Circuit Breaker: Ein Sprung über seinem Limit pausiert den Feed, bis er geprüft ist.
6. Solidity-Beispiel (Pull-Muster)
interface IMarketApiOracle {
struct PriceReport { bytes32 feedId; int256 price; uint64 timestamp; uint64 validUntil; uint8 marketStatus; uint32 spreadBps; }
function submit(PriceReport calldata r, bytes calldata sig) external returns (bool);
function getPriceNoOlderThan(bytes32 feedId, uint256 maxAge) external view returns (int256 price, uint64 timestamp);
}
contract GoldVault {
IMarketApiOracle immutable oracle;
bytes32 constant XAUUSD = keccak256("XAUUSD");
constructor(IMarketApiOracle o) { oracle = o; }
function settle(IMarketApiOracle.PriceReport calldata r, bytes calldata sig) external {
oracle.submit(r, sig);
(int256 price, ) = oracle.getPriceNoOlderThan(XAUUSD, 60); // reverts unless OPEN and at most 60 s old
// ... use price (8 decimals)
}
}7. JavaScript-Beispiel (ethers v6)
const res = await fetch("https://api.marketapi.app/v1/oracle/report?symbols=XAUUSD&chain_id=10",
{ headers: { Authorization: `Bearer ${process.env.API_KEY}` } });
const { data, refused } = await res.json();
if (!data.length) throw new Error(refused[0]?.reason); // e.g. market closed or stale
const r = data[0];
const report = ethers.AbiCoder.defaultAbiCoder().decode(
["tuple(bytes32,int256,uint64,uint64,uint8,uint32)"], r.report)[0];
await vault.settle(report, r.signature); // your contract calls oracle.submit(...)8. Ablehnungen und Fehler
refused-Einträge listen Symbole, die nicht signiert wurden, mit Grund, zum Beispiel derzeit kein verlässlicher Kurs (STALE) oder ein geschlossener Markt. Sie werden nicht berechnet.oracle_unavailable(503): Der Signierdienst ist kurz nicht verfügbar; wiederholen Sie mit Backoff.- On-Chain-Reverts:
InvalidSignature(falscher Signer, falsche Chain oder falscher Vertrag),ReportExpired,FutureTimestamp,InvalidPrice,InvalidStatus,NoPrice(Feed hat noch keinen Kurs),FeedTripped(Circuit Breaker),MarketNotOpenundPriceTooOld(vongetPriceNoOlderThan),IsPaused.
9. Bewährte Vorgehensweisen
- Rufen Sie den Bericht direkt vor dem Senden der Transaktion ab; Berichte laufen nach etwa einer Minute ab.
- Lesen Sie immer mit
getPriceNoOlderThanund einem zu Ihrem Produkt passenden Höchstalter. - Behandeln Sie CLOSED-Märkte ausdrücklich (Wochenenden, Feiertage), zum Beispiel durch Abrechnung zur nächsten Eröffnung.
- Testen Sie zuerst im Testnet und ändern Sie danach nur Vertragsadresse und Chain-ID.
- Bewahren Sie API-Schlüssel auf Ihrem Server auf, nie in einer Webseite.