Acelon is a decentralized price oracle service built on the Acurast network. It provides real-time cryptocurrency price data by aggregating information from multiple exchanges, ensuring high reliability and accuracy.
- Fetches price data from multiple cryptocurrency exchanges
- Implements caching to optimize performance and reduce API calls
- Supports various aggregation methods (median, mean, min, max)
- Allows price validation
- Allows custom configuration of data sources and parameters
- Provides signed price data for on-chain verification
- Supports multiple blockchain protocols (Substrate, EVM, WASM, Tezos)
- Includes exchange API health checking functionality
-
Clone the repository:
git clone https://github.com/acurast/acurast-oracle-service.git cd acurast-oracle-service
-
Install dependencies:
yarn install
To build the project, run:
yarn bundle
This will generate a file called bundle.js
in the /dist
directory. This is the file that will be running on the Acurast processors, including all dependencies.
To fetch prices, send a JSON-RPC request with the following structure:
{
"jsonrpc": "2.0",
"id": 1,
"method": "fetchPrices",
"params": {
"pairs": [
{ "from": "BTC", "to": "USD" },
{ "from": "ETH", "to": "USD" }
],
"protocol": "Substrate",
"aggregation": ["median", "mean"],
"minSources": 3,
"tradeAgeLimit": 300000,
"maxValidationDiff": 0.1
}
}
-
pairs
: An array of currency pairs to fetch prices for. Each pair consists of:-
from
: The from currency (e.g., "BTC") -
to
: The to currency (e.g., "USD") -
decimals
: (Optional) Decimals of the price (Default: 8) -
exchanges
(optional): An array of exchange IDs to fetch prices from. If not provided, all available exchanges will be used. -
price
(optional): A client-provided price(s) for validation. -
timestamp
(optional): A client-provided timestamp for validation.The prices have to match the aggregation types that were requested. Provide prices that match requested aggregations in the same order.
-
-
protocol
: The blockchain protocol for which to generate signed price data. Possible values are:"Substrate"
"EVM"
"WASM"
"Tezos"
-
aggregation
: The method(s) used to aggregate prices from multiple sources. Can be a single value or an array. Possible values are:"median"
(default if not specified)"mean"
"min"
"max"
-
minSources
(optional): The minimum number of valid price sources required to consider the aggregated price valid. Default is 3. -
tradeAgeLimit
(optional): The maximum age (in milliseconds) of a trade to be considered valid. Default is 5 minutes (300000 ms). -
maxSourcesDeviation
(optional): The maximum allowed standard deviation among prices from different sources. If exceeded, an error is thrown. -
maxValidationDiff
(optional): The maximum allowed percentage difference between the aggregated price and a client-provided price (if given). Default is 0.05 (5%).
The oracle supports fetching price data from the following exchanges:
Exchange ID | Exchange Name |
---|---|
BNU | Binance US |
BNC | Binance |
CBP | Coinbase |
BFX | Bitfinex |
KRK | Kraken |
BYB | Bybit |
GEM | Gemini |
KUC | Kucoin |
GIO | Gate IO |
CRY | Crypto.com |
HTX | HTX |
MEXC | MEXC |
WBIT | Whitebit |
OKX | OKX |
UPB | Upbit |
The fetchPrices
method returns a JSON-RPC response with the following structure:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"priceInfos": [
{
"from": "BTC",
"to": "USD",
"decimals": 6,
"price": {
"median": 50000000000,
"mean": 50010000000
},
"timestamp": 1623456789,
"rawPrices": [49950.5, 50100.75, 49980.25],
"stdDev": 64.33,
"sources": [
{ "exchangeId": "BNC", "certificate": "..." },
{ "exchangeId": "CBP", "certificate": "..." },
{ "exchangeId": "BFX", "certificate": "..." }
]
}
],
"signedPrices": [
{
"data": {
"from": "BTC",
"to": "USD",
"decimals": 6,
"price": [50000000000, 50010000000],
"timestamp": 1623456789,
"sources": [
{ "exchangeId": "BNC", "certificate": "..." },
{ "exchangeId": "CBP", "certificate": "..." },
{ "exchangeId": "BFX", "certificate": "..." }
],
"requestHash": "..."
},
"packedPrice": "...",
"signature": "..."
}
],
"version": "1.0.0"
}
}
-
priceInfos
: An array of price information for each requested pair.from
: the from symbol.to
: the to symbol.decimals
: decimals for the price.price
: An object containing the aggregated prices for each requested aggregation method.validation
: An object indicating whether each aggregated price passed the validation check against the client-provided price.timestamp
: The Unix timestamp of the price data in milliseconds.rawPrices
: An array of the prices from each source before aggregation.stdDev
: The standard deviation of the raw prices.sources
: Map with exchangeId to api certificate.
-
signedPrices
: An array of signed price data for on-chain verification.data
: The price data that was signed, including the hash of the request parameters.packedPrice
: The price data packed into the specific chain format.signature
: The signature of the packed price data.
-
version
: The version of the oracle software.
To check the health status of exchanges, send a JSON-RPC request with the following structure:
{
"jsonrpc": "2.0",
"id": 2,
"method": "checkExchangeHealth",
"params": {
"exchanges": ["BNU", "CBP", "KRK"]
}
}
exchanges
(optional): An array of exchange IDs to check. If not provided, all configured exchanges will be checked.
The response will include the health status and response time (if available) for each requested exchange.
If there's an error during the price fetching process, the oracle will return an error response:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32000,
"message": "fetchPrices error",
"data": "Not enough sources for BTC-USD, 2 / 3 sources fetched"
}
}
The error codes follow the JSON RPC 2.0 standard
To ping the oracle, send a JSON-RPC request with the following structure:
{
"jsonrpc": "2.0",
"id": 1,
"method": "ping"
}
The response will include a status and timestamp:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"status": "alive",
"timestamp": 1623456789000
}
}
src/index.ts
: Main entry pointsrc/methods/
: Core functionality for fetching and processing pricessrc/utils/
: Utility functions and helper modulessrc/config/
: Configuration for supported exchangessrc/types.ts
: TypeScript type definitions
To add a new exchange:
- Add the exchange configuration to
src/config/exchanges.ts
- Implement the
extractPriceData
function for the new exchange - Add any necessary URL templates
- Implement the
healthEndpoint
andvalidateHealthResponse
functions for the new exchange
To test the project, run:
yarn test
This project is licensed under the MIT License.