This is a standalone version of Umee's fantastic work migrating Terra's oracle-feeder app to Go, and integrating it more closely with the Cosmos SDK.
The list of current supported providers:
- Astroport
- Binance
- BinanceUS
- Bitfinex
- Bitget
- Bitmart
- Bitstamp
- Bybit
- Camelot DEX
- Coinbase
- Crypto.com
- Curve
- FIN
- Gate.io
- HitBTC
- Huobi
- Kraken
- Kucoin
- LBank
- MEXC
- Okx
- Osmosis
- PancakeSwap (Ethereum)
- Phemex
- Poloniex
- Pyth
- UniswapV3
- WhiteWhale
- XT.COM
The price-feeder
tool runs off of a single configuration file. This configuration
file defines what exchange rates to fetch and what providers to get them from.
In addition, it defines the oracle's keyring and feeder account information.
The keyring's password is defined via environment variables or user input.
More information on the keyring can be found here
Please see the example configuration for more details.
price-feeder /path/to/price_feeder_config.toml
An extensive installation guide can be found here.
The server
section contains configuration pertaining to the API served by the
price-feeder
process such the listening address and various HTTP timeouts.
The rpc
section contains the Tendermint and Cosmos application gRPC endpoints.
These endpoints are used to query for on-chain data that pertain to oracle
functionality and for broadcasting signed pre-vote and vote oracle messages.
A set of options for the application's telemetry, which is disabled by default. An in-memory sink is the default, but Prometheus is also supported. We use the cosmos sdk telemetry package.
The account
section contains the oracle's feeder and validator account information.
These are used to sign and populate data in pre-vote and vote oracle messages.
The keyring
section contains Keyring related material used to fetch the key pair
associated with the oracle account that signs pre-vote and vote oracle messages.
The healthchecks
section defines optional healthcheck endpoints to ping on successful
oracle votes. This provides a simple alerting solution which can integrate with a service
like healthchecks.io. It's recommended to configure additional
monitoring since third-party services can be unreliable.
Deviation thresholds allow validators to set a custom amount of standard deviations around the median which is helpful if any providers become faulty. It should be noted that the default for this option is 1 standard deviation.
[[deviation_thresholds]]
base = "USDT"
threshold = "2"
This option allows validators to set the minimum prices sources needed for specific assets. This might be necessary, if there are less than three providers available for a certain asset.
[[provider_min_overrides]]
denoms = ["QCKUJI", "QCMNTA"]
providers = 1
Url sets are named arrays of endpoint urls, that can be reused in endpoint configurations.
[url_set.rest_kujira]
urls = [
"https://rest.cosmos.directory/kujira",
]
[[provider_endpoints]]
name = "finv2"
url_set = "rest_kujira"
The provider_endpoints option enables validators to setup their own API endpoints for a given provider.
[[provider_endpoints]]
name = "finv2"
urls = [
"https://rest.cosmos.directory/kujira",
]
The contract_addresses
sections contain a mapping of base/denom pair to the pool addresses of supported decentralized exchanges.
[contract_addresses.finv2]
KUJIUSDC = "kujira14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sl4e867"
MNTAUSDC = "kujira1ws9w7wl68prspv3rut3plv8249rm0ea0kk335swye3sl2slld4lqdmc0lv"
The currency_pairs
sections contains one or more exchange rates along with the
providers from which to get market data from. It is important to note that the
providers supplied in each currency_pairs
must support the given exchange rate.
For example, to get multiple price points on ATOM, you could define currency_pairs
as follows:
[[currency_pairs]]
base = "ATOM"
quote = "USDT"
providers = [
"binance",
]
[[currency_pairs]]
base = "ATOM"
quote = "USD"
providers = [
"kraken",
"osmosis",
]
Providing multiple providers is beneficial in case any provider fails to return market data or reports a price that deviates too much and should be considered wrong. Prices per exchange rate are submitted on-chain via pre-vote and vote messages using a volume-weighted average price (VWAP).
Provider weight sets the volume for the given providers of a specific denom. This can be used manually set the impact of specific providers during the vwap calculation or create some kind of ordered failover mechanism.
[provider_weight.STATOM]
provider1 = 100
provider2 = 0.001
provider3 = 0
In this example the resulting price will be following provider1 as long as it is available (100k times more weight than provider2). If provider1 fails, the resulting price will follow provider2, and if that fails it too, the resulting price is the one reported by provider3. All assuming the deviation of the all prices are within the configured range.
Our keyring must be set up to sign transactions before running the price feeder.
Additional info on the different keyring modes is available here.
Please note that the test
and memory
modes are only for testing purposes.
Do not use these modes for running the price feeder against mainnet.
The keyring dir
and backend
are defined in the config file.
You may use the PRICE_FEEDER_PASS
environment variable to set up the keyring password.
Ex :
export PRICE_FEEDER_PASS=keyringPassword
If this environment variable is not set, the price feeder will prompt the user for input.