توثيق الأوراكل
أسعار موقّعة للفوركس والمعادن الثمينة تتحقق منها عقودك الذكية على السلسلة. نظرة عامة: صفحة الأوراكل · بصيغة قابلة للقراءة آليًا: /v1/oracle/feeds، /v1/oracle/catalog.
1. كيف يعمل
- تطلب الواجهة الخلفية لديك تقريرًا موقّعًا:
GET https://api.marketapi.app/v1/oracle/report?symbols=XAUUSD&chain_id=10(مفتاح API بنطاقread:oracle؛ يُحتسب لكل تقرير موقّع). - تمرّر معاملتك التقرير والتوقيع إلى عقد التحقق، الذي يتحقق من توقيع EIP-712 وانتهاء الصلاحية والسلسلة وقاطع الدارة الخاص به، ثم يخزّن السعر.
- في المعاملة نفسها يقرأ عقدك السعر مع شرط الحداثة. يستخدم نمط السحب هذا السعر الحالي دائمًا.
تُدفع الأسعار المطلوبة عبر الـ API أيضًا إلى السلسلة تلقائيًا من حين لآخر، لكن لا تعتمد أبدًا على سعر مخزَّن دون فحص حداثته.
2. الشبكات والعقود
| الشبكة | معرّف السلسلة | عقد التحقق |
|---|---|---|
| Optimism | 10 | 0xaeF7f701acFB42267015D3F593ce17CF536Afd6B · المستكشف |
| Optimism Sepolia شبكة اختبار | 11155420 | 0xBBf36E7Cd75494f28E02C5698EaD35fF4960a943 · المستكشف |
عنوان المُوقِّع: 0x83fa2d8836525251FAd214A78A72038D0864f877. شبكات الاختبار مخصصة للاختبار المجاني دون ضمانات للخدمة.
3. المصادر
لكل مصدر معرّف دائم: feedId = keccak256(symbol). وتستخدم الأسعار 8 منازل عشرية.
| الرمز | 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. التقرير الموقّع
نطاق EIP-712: الاسم MarketAPI Oracle، والإصدار 2، ومعرّف السلسلة، وعنوان عقد التحقق. النوع:
PriceReport(bytes32 feedId,int256 price,uint64 timestamp,uint64 validUntil,uint8 marketStatus,uint32 spreadBps)
- price: السعر الأوسط بـ 8 منازل عشرية.
- timestamp: وقت السعر (بثواني UTC)؛ validUntil: تنتهي صلاحية التقرير بعد نحو دقيقة.
- marketStatus: 1 OPEN، 2 CLOSED (السعر الرسمي الأخير، مثلًا في عطلات نهاية الأسبوع)، 3 HALTED.
- spreadBps: فارق العرض والطلب بنقاط الأساس؛ ومع عدة وسطاء يعكس أيضًا مدى تباعدهم.
يحتوي رد الـ API على report (مرمَّز بـ ABI) وsignature (65 بايت): وهما بالضبط وسيطا submit.
5. دوال العقد
submit(PriceReport r, bytes sig) returns (bool): تحقّق وخزّن؛ ويُتجاهَل إن كان هناك سعر مساوٍ أو أحدث مخزَّن.submitBatch(PriceReport[] rs, bytes[] sigs): عدة مصادر في معاملة واحدة؛ وتُتخطّى الإدخالات غير الصالحة.getPrice(bytes32 feedId): آخر سعر مخزَّن وطابعه الزمني؛ يُرجع (revert) ما دام المصدر بلا سعر بعد.getPriceNoOlderThan(bytes32 feedId, uint256 maxAge): يُرجع ما لم يكن السوق OPEN والسعر حديثًا بما يكفي. استخدمها لإجراءات التداول.
لكل مصدر قاطع دارة: القفزة الأكبر من حدّه توقف المصدر حتى تتم مراجعته.
6. مثال Solidity (نمط السحب)
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 (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. حالات الرفض والأخطاء
- تسرد إدخالات
refusedالرموز التي لم تُوقَّع مع السبب، مثل لا سعر موثوق الآن (STALE) أو سوق مغلق. ولا تُحتسب عليها رسوم. oracle_unavailable(503): خدمة التوقيع غير متاحة لفترة وجيزة؛ أعد المحاولة مع تأخير متزايد.- حالات الإرجاع على السلسلة:
InvalidSignature(مُوقِّع أو سلسلة أو عقد خاطئ)، وReportExpired، وFutureTimestamp، وInvalidPrice، وInvalidStatus، وNoPrice(لا سعر للمصدر بعد)، وFeedTripped(قاطع الدارة)، وMarketNotOpenوPriceTooOld(منgetPriceNoOlderThan)، وIsPaused.
9. أفضل الممارسات
- اجلب التقرير قبيل إرسال المعاملة مباشرة؛ تنتهي صلاحية التقارير بعد نحو دقيقة.
- اقرأ دائمًا عبر
getPriceNoOlderThanوبحد أقصى للعمر يناسب منتجك. - تعامل صراحةً مع الأسواق المغلقة CLOSED (عطلات نهاية الأسبوع والعطل الرسمية)، مثلًا بالتسوية عند الافتتاح التالي.
- اختبر على شبكة الاختبار أولًا، ثم غيّر عنوان العقد ومعرّف السلسلة فقط.
- احتفظ بمفاتيح الـ API على خادمك، ولا تضعها أبدًا في صفحة ويب.