Oráculo de precios on-chain · fuentes de precios de activos reales
Oráculo de precios para contratos inteligentes: divisas, oro, índices y acciones on-chain
Obtén un informe de precio firmado de nuestra API y pásalo a tu contrato. Nuestro contrato verificador comprueba la firma on-chain, así tu contrato puede confiar en el precio sin confiar en el mensajero.
Cómo funciona
- Obtén un informe firmado:
GET /oracle/reportcon tu clave API. - Envíalo en tu transacción: nuestro contrato verificador comprueba la firma con
ecrecover. - Usa el precio verificado; recházalo si es demasiado antiguo para tu caso de uso.
Los informes son datos tipados EIP-712 PriceReport(bytes32 feedId,int256 price,uint64 timestamp,uint64 validUntil,uint8 marketStatus,uint32 spreadBps), ligados a una cadena y a un contrato verificador (sin reutilización en otro sitio) y aceptados solo hasta validUntil, alrededor de un minuto tras la firma (no se pueden acumular informes favorables). Los precios son el punto medio entre compra y venta con 8 decimales; spreadBps es el diferencial compra-venta. Cuando envías un informe en tu propia transacción, pagas ese gas. Nuestro relayer también guarda on-chain de vez en cuando las fuentes con demanda (lectura gratuita), pero comprueba siempre la antigüedad de un precio guardado.
Horario de mercado
Cada informe indica el estado del mercado: OPEN (un precio en vivo, de como máximo 60 segundos), CLOSED (el último precio oficial antes del cierre, igual para todos, firmado en cualquier momento mientras el mercado está cerrado) o HALTED (negociación suspendida). getPriceNoOlderThan solo devuelve precios OPEN, así un precio de cierre nunca puede pasar por uno en vivo. Los tokens respaldados por activos deberían liquidar las órdenes dadas con el mercado cerrado al siguiente precio OPEN (forward pricing, como hacen los fondos y ETF).
Cortacircuitos
Cada fuente puede tener un salto máximo permitido. Un movimiento mayor no se guarda: la fuente se pausa hasta que la hayamos revisado y reabierto, así un precio erróneo o manipulado nunca llega a tu contrato.
Fuentes
| Símbolo | 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 |
Redes
| Red | ID de cadena | Contrato verificador |
|---|---|---|
| Optimism | 10 | 0xaeF7f701acFB42267015D3F593ce17CF536Afd6B |
| Optimism Sepolia testnet | 11155420 | 0xBBf36E7Cd75494f28E02C5698EaD35fF4960a943 |
Dirección del firmante: 0x83fa2d8836525251FAd214A78A72038D0864f877. Lista legible por máquina: /oracle/feeds.
Integrar
1. Obtén un informe firmado
curl -H "Authorization: Bearer $API_KEY" \
"https://api.marketapi.app/v1/oracle/report?symbols=EURUSD&chain_id=10"
Devuelve report (la tupla codificada en ABI) y signature (65 bytes) por símbolo. Tu clave necesita el ámbito read:oracle.
2. Verifícalo en tu contrato
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); // verifies, stores if newer
function getPriceNoOlderThan(bytes32 feedId, uint256 maxAge)
external view returns (int256 price, uint64 timestamp); // OPEN and fresh only, else reverts
function getPrice(bytes32 feedId) external view
returns (int256 price, uint64 timestamp, uint8 marketStatus, uint32 spreadBps); // incl. CLOSED
}
contract MyVault {
IMarketApiOracle immutable oracle;
bytes32 constant EURUSD = keccak256("EURUSD");
constructor(IMarketApiOracle o) { oracle = o; }
function act(IMarketApiOracle.PriceReport calldata r, bytes calldata sig) external {
oracle.submit(r, sig); // reverts on a bad signature
(int256 price, ) = oracle.getPriceNoOlderThan(EURUSD, 60); // 8 decimals
// ... use price ...
}
}
Los consumidores al estilo Chainlink pueden leer una fuente mediante el MarketApiFeedAdapter (latestRoundData(), AggregatorV3Interface).
Precios
5 crédito(s) por informe firmado, pagado(s) con tu saldo normal de la API. Leer precios ya guardados on-chain es gratis.
Casos de uso de nuestras fuentes de precios on-chain
- Activos tokenizados y RWA: pon precio a acciones tokenizadas, tokens respaldados por oro y otros activos del mundo real con datos de precios que tienen en cuenta el horario de mercado.
- Préstamos DeFi y colateral: valora colateral respaldado por divisas y materias primas con precios frescos y verificables y comprobaciones de antigüedad seguras para las liquidaciones.
- Activos sintéticos y divisas on-chain: liquida posiciones sintéticas de divisas, índices y materias primas contra precios de referencia firmados.
- Stablecoins y pagos: convierte entre divisas on-chain con tipos EUR/USD, GBP/USD y otros en vivo.
¿Por qué un oráculo pull firmado?
Los oráculos push se actualizan según un calendario y alguien paga gas por cada actualización. Con un oráculo pull tu contrato obtiene un precio fresco y firmado criptográficamente justo cuando lo necesita: menor coste, datos más frescos y la misma verificación on-chain. El estado del mercado, el diferencial compra-venta y la caducidad forman parte de cada informe firmado.
Preguntas frecuentes del oráculo de precios
¿Qué es un oráculo de precios blockchain?
Un oráculo de precios lleva precios de mercado off-chain a los contratos inteligentes. Nuestro oráculo firma cada precio con una firma EIP-712; tu contrato la verifica on-chain con ecrecover antes de usarlo, así el precio no puede falsificarse por el camino.
¿Qué activos cubren las fuentes de precios?
Pares de divisas como EUR/USD, metales preciosos como el oro (XAU/USD) y la plata, índices bursátiles y acciones individuales, según la lista de fuentes publicada en esta página. Cada fuente tiene un feedId fijo (keccak256 del símbolo).
¿Sirve para RWA y activos tokenizados?
Sí. Los informes incluyen el estado del mercado (abierto, cerrado, suspendido), así las acciones tokenizadas, las materias primas y otros activos reales pueden aplicar forward pricing fuera del horario de mercado en lugar de operar con un precio desfasado.
¿Es el oráculo compatible con Chainlink?
Cada fuente puede leerse mediante un adaptador que implementa la AggregatorV3Interface de Chainlink (latestRoundData), así el código DeFi existente que lee fuentes de precios al estilo Chainlink funciona con cambios mínimos.
¿Cómo se evita la manipulación?
Los informes caducan en alrededor de un minuto y deben ser más recientes que el precio guardado, un cortacircuitos por fuente pausa una fuente tras un salto anómalo y, con varios brókers, el precio es la mediana de fuentes independientes sin valores atípicos.
¿Quién paga el gas?
Es un oráculo pull: tu aplicación envía el informe firmado en su propia transacción y paga ese gas. Nuestro relayer también guarda on-chain de vez en cuando las fuentes con demanda; leer los precios guardados es gratis, pero comprueba su antigüedad antes de usarlos.
¿Qué blockchains se admiten?
Cualquier cadena EVM donde esté desplegado el contrato verificador, por ejemplo Ethereum, Base, Arbitrum, Optimism, BNB Smart Chain y Polygon y sus testnets; la lista actual se muestra arriba.
Recomendado: el patrón pull (precios siempre frescos)
No confíes en el precio ya guardado on-chain. Obtén un informe recién firmado y envíalo en la misma transacción que lo usa: tu contrato siempre ve el precio actual y solo pagas tus propias actualizaciones.
// 1) off-chain: GET https://api.marketapi.app/v1/oracle/report?symbols=EURUSD&chain_id=CHAIN_ID (header: Authorization: Bearer KEY)
// 2) on-chain: verify, store and use the report atomically
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 MyVault {
IMarketApiOracle immutable oracle;
bytes32 constant EURUSD = keccak256("EURUSD");
constructor(IMarketApiOracle o) { oracle = o; }
function settle(IMarketApiOracle.PriceReport calldata r, bytes calldata sig) external {
oracle.submit(r, sig); // ignored if an equal/newer price is stored
(int256 price, ) = oracle.getPriceNoOlderThan(EURUSD, 60); // reverts unless OPEN and fresh
// ... use price (8 decimals)
}
}
Los campos report y signature del informe que da la API son exactamente los dos argumentos de submit. Los informes son válidos alrededor de un minuto, así que obténlos justo antes de enviar la transacción.
Aviso de riesgo. Los precios son datos de mercado indicativos de nuestra fuente, no un centro de ejecución. Los contratos inteligentes que mueven fondos según cualquier oráculo deben comprobar la antigüedad, gestionar las actualizaciones que falten y limitar el impacto de un precio erróneo. Lee las condiciones antes de confiar en el oráculo en producción.