Injective's Oracle with dynamic price feeds (for External Integrations)

injective-price-oracle

Injective's Oracle with dynamic price feeds. Allows anyone to start their own pre-approved price submission process to the oracle module on the Injective Chain.

Getting Started

First, make sure your Go env is correctly configured, download a distribution from https://go.dev/dl/ the minimum required version is 1.17.

Clone this repo:

git clone [email protected]:InjectiveLabs/injective-price-oracle-ext.git
cd injective-price-oracle-ext
make install

After binary has been built, it should be available for usage in CLI:

$ injective-price-oracle version

Version dev (77a1017)
Compiled at 20220203-2207 using Go go1.17.3 (arm64)

Environment

Before starting the injective-price-oracle service, make sure you copy a template .env file and fill the correct values, especially for the Cosmos keys. You can use latest injectived release to manage the keyring dir. It's never recommended to use private key as plaintext in ORACLE_COSMOS_PK, except for testing.

More info on private keys: A Guide to Private Key Management (Oracle)

cp .env.example .env

Running with dynamic feeds

This is an example that loads all dynamic feeds from examples/ dir! Make sure to specify correct path to your TOML dir.

$ injective-price-oracle start --dynamic-feeds examples


INFO[0000] using Cosmos Sender inj128jwakuw3wrq6ye7m4p64wrzc5rfl8tvwzc6s8
INFO[0000] waiting for GRPC services
INFO[0001] found 1 dynamic feed configs
INFO[0001] got 1 enabled price feeds                     svc=oracle
INFO[0001] initialized 1 price pullers                   svc=oracle
INFO[0001] starting pullers for 1 feeds                  svc=oracle
INFO[0007] PullPrice (pipeline run) done in 1.0506275s   dynamic=true provider=binance_v3 svc=oracle ticker=INJ/USDT
INFO[0014] sent Tx in 2.72982375s                        batch_size=1 hash=1D7D02BDBAEC200BD585E90215459E93C760A1317EFF9D83B822FA4F34AD6A03 svc=oracle timeout=true
INFO[0067] PullPrice (pipeline run) done in 314.4035ms   dynamic=true provider=binance_v3 svc=oracle ticker=INJ/USDT
INFO[0073] sent Tx in 1.706471708s                       batch_size=1 hash=6E3A6C8F7706DB0B0355C5691A628A56CD5A87BB14877D2F0D151178FCF2784A svc=oracle timeout=true
INFO[0128] PullPrice (pipeline run) done in 310.32875ms  dynamic=true provider=binance_v3 svc=oracle ticker=INJ/USDT
INFO[0133] sent Tx in 1.776902583s                       batch_size=1 hash=29D615079A891F25E5ADE167E78D478F8AA99CEEFED7DB47B3F5E71BFEDEB582 svc=oracle timeout=true

Adding new feeds

There are two ways to add new feeds.

Dynamic feeds (TOML)

Most preferred way is to create dynamic feeds using DOT Syntax, using the Chainlink innovation in this area (see Job Pipelines).

Check out this most simple example:

parsePrice -> multiplyDecimals """">
provider = "binance_v3"
ticker = "INJ/USDT"
pullInterval = "1m"
observationSource = """
   ticker [type=http method=GET url="https://api.binance.com/api/v3/ticker/price?symbol=INJUSDT"];
   parsePrice [type="jsonparse" path="price"]
   multiplyDecimals [type="multiply" times=1000000]

   ticker -> parsePrice -> multiplyDecimals
"""

Beautiful, isn't it? The observationSource provided in DOT Syntax, while the rest of the file is a TOML config. Place these configs under any names into a special dir and start the oracle referencing the dir with --dynamic-feeds

.

See the full documentation on the supported Tasks that you can use.

List of supported pipeline tasks:

  • http - docs ๐Ÿ”—
  • mean - docs ๐Ÿ”—
  • median - docs ๐Ÿ”—
  • mode - docs ๐Ÿ”—
  • sum - docs ๐Ÿ”—
  • multiply - docs ๐Ÿ”—
  • divide - docs ๐Ÿ”—
  • jsonparse - docs ๐Ÿ”—
  • any - docs ๐Ÿ”—
  • ethabiencode - docs
  • ethabiencode2 - docs ๐Ÿ”—
  • ethabidecode - docs ๐Ÿ”—
  • ethabidecodelog - docs ๐Ÿ”—
  • merge - docs ๐Ÿ”—
  • lowercase
  • uppercase

More can be added if needed.

List of config fields:

  • provider - name (or slug) of the used provider, used for logging purposes.
  • ticker - name of the ticker on the Injective Chain. Used for loading feeds for enabled tickers.
  • pullInterval time duration spec in Go-flavoured duration syntax. Cannot be negative or less than "1s". Valid time units are "ns", "us" (or "ยตs"), "ms", "s", "m", "h".
  • observationSource - pipeline spec in DOT Syntax

Native Go code

Yes, you can also simply fork this repo and add own native implementations of the price feeds. There is a Binance example provided in feed_binance.go. Any complex feed can be added as long as the implementation follows this Go interface:

type PricePuller interface {
	Provider() FeedProvider
	ProviderName() string
	Symbol() string
	Interval() time.Duration

	// PullPrice method must be implemented in order to get a price
	// from external source, handled by PricePuller.
	PullPrice(ctx context.Context) (price decimal.Decimal, err error)
}
Owner
Injective Protocol
Building the future of decentralized exchange
Injective Protocol
Similar Resources

CSI Driver for dynamic provisioning of Persistent Local Volumes for Kubernetes using LVM.

CSI Driver for dynamic provisioning of Persistent Local Volumes for Kubernetes using LVM.

OpenEBS LVM CSI Driver CSI driver for provisioning Local PVs backed by LVM and more. Project Status Currently the LVM CSI Driver is in alpha

Dec 24, 2022

Dothill (Seagate) AssuredSAN dynamic provisioner for Kubernetes (CSI plugin).

Dothill-csi dynamic provisioner for Kubernetes A dynamic persistent volume (PV) provisioner for Dothill AssuredSAN based storage systems. Introduction

Oct 11, 2022

Open Service Mesh (OSM) is a lightweight, extensible, cloud native service mesh that allows users to uniformly manage, secure, and get out-of-the-box observability features for highly dynamic microservice environments.

Open Service Mesh (OSM) is a lightweight, extensible, cloud native service mesh that allows users to uniformly manage, secure, and get out-of-the-box observability features for highly dynamic microservice environments.

Open Service Mesh (OSM) Open Service Mesh (OSM) is a lightweight, extensible, Cloud Native service mesh that allows users to uniformly manage, secure,

Jan 2, 2023

Dynamic Application Security Testing (DAST) for Cloud

Dynamic Application Security Testing (DAST) for Cloud

Dynamic Application Security Testing (DAST) for Cloud Probr analyzes the complex behaviours and interactions in your cloud resources to enable enginee

Dec 15, 2022

Enable dynamic and seamless Kubernetes multi-cluster topologies

Enable dynamic and seamless Kubernetes multi-cluster topologies Explore the docs ยป View Demo ยท Report Bug ยท Request Feature About the project Liqo is

Dec 30, 2022

Envoy file based dynamic routing using kubernetes config map

Envoy File Based Dynamic Routing Config mapใ‚’ไฝฟ็”จใ—ใฆEnvoy File Based Dynamic Routingใ‚’ๅฎŸ็พใ—ใพใ™ใ€‚ ๆฆ‚่ฆ ใ‚ขใƒผใ‚ญใƒ†ใ‚ฏใƒใƒฃใจใ—ใฆใฏใ€ +----------+ +--------------+ +-----------

Dec 30, 2022

Dynamic service configuration with etcd.

dynconf This Go package provides a dynamic service configuration backed by etcd, so there should be no need to redeploy a service to change its settin

Dec 6, 2021

A dynamic docker-redis-traefik discovery agent

traefik-kop A dynamic docker-redis-traefik discovery agent. Solves the problem of running a non-Swarm/Kubernetes multi-host cluster with a single pu

Dec 23, 2022

Becca - A simple dynamic language for exploring language design

Becca A simple dynamic language for exploring language design What is Becca Becc

Aug 15, 2022
Comments
  • The service fails to broadcast the price feed when it's null on the chain

    The service fails to broadcast the price feed when it's null on the chain

    Hey @xlab I found an issue with the price oracle.

    If the price feed hasn't been submitted before on-chain and the service starts you end up with the error below. I submitted the price feed once with sdk-python using the same relayer address, it was submitted normally with no issues and then the price started broadcasting txs just fine and updating the feed.

    I didn't even touch the docker container in the yaml file neither stop the process after broadcasting the tx from sdk-python. The moment the price feed was on the chain from sdk-python it started submitting txs normally.

    image

    time="2022-03-22T09:51:57Z" level=error msg="failed to commit msg batch: null" error="4483E42CEB308CDC5A7C9B202E103F164FF1A4A54E4F1700CE310898561C696E: tx timed out" module=sdk-go size=1 svc=cosmosClient time="2022-03-22T09:51:57Z" level=error msg="failed to SyncBroadcastMsg" batch_size=1 error="4483E42CEB308CDC5A7C9B202E103F164FF1A4A54E4F1700CE310898561C696E: tx timed out" svc=oracle timeout=true time="2022-03-22T09:52:07Z" level=warning msg="metrics init failed, will retry in 1 min" error="statsd init failed: dial udp: lookup host.docker.internal: no such host" time="2022-03-22T09:52:15Z" level=info msg="PullPrice (pipeline run) done in 81.165393ms" dynamic=true provider=nftbank-estimates-v2 svc=oracle ticker=BAYC/WETH time="2022-03-22T09:52:57Z" level=error msg="failed to commit msg batch: null" error="4483E42CEB308CDC5A7C9B202E103F164FF1A4A54E4F1700CE310898561C696E: tx timed out" module=sdk-go size=1 svc=cosmosClient time="2022-03-22T09:52:57Z" level=error msg="failed to SyncBroadcastMsg" batch_size=1 error="4483E42CEB308CDC5A7C9B202E103F164FF1A4A54E4F1700CE310898561C696E: tx timed out" svc=oracle timeout=true time="2022-03-22T09:53:07Z" level=warning msg="metrics init failed, will retry in 1 min" error="statsd init failed: dial udp: lookup host.docker.internal: no such host" time="2022-03-22T09:53:15Z" level=info msg="PullPrice (pipeline run) done in 79.507951ms" dynamic=true provider=nftbank-estimates-v2 svc=oracle ticker=BAYC/WETH time="2022-03-22T09:53:18Z" level=error msg="set price Tx error: code: 11\ncodespace: sdk\ndata: ""\nevents:\n- attributes:\n - index: false\n key: YWNjX3NlcQ==\n value: aW5qMWN5OHJwNGUyY3ptZjducnN6N2VrcWZmeXp0dnVkOXZ5cm5kem12LzA=\n type: tx\n- attributes:\n - index: false\n key: c2lnbmF0dXJl\n value: RmZzUG5TYWY3UGZ6ejh3QWVDUytnR01nVDlBbHJRWHhCYWh3OXVVdEMrWk9wQUxQM1h4anAyVFd5U3g0ODhaTkpkaDZvdEZ0V3FmTnhwb0pXL1lUdndBPQ==\n type: tx\n- attributes:\n - index: false\n key: c3BlbmRlcg==\n value: aW5qMWN5OHJwNGUyY3ptZjducnN6N2VrcWZmeXp0dnVkOXZ5cm5kem12\n - index: false\n key: YW1vdW50\n value: NDQ2MDE1MDAwMDAwMDAwaW5q\n type: coin_spent\n- attributes:\n - index: false\n key: cmVjZWl2ZXI=\n value: aW5qMTd4cGZ2YWttMmFtZzk2MnlsczZmODR6M2tlbGw4YzVsNnM1eWU5\n - index: false\n key: YW1vdW50\n value: NDQ2MDE1MDAwMDAwMDAwaW5q\n type: coin_received\n- attributes:\n - index: false\n key: cmVjaXBpZW50\n value: aW5qMTd4cGZ2YWttMmFtZzk2MnlsczZmODR6M2tlbGw4YzVsNnM1eWU5\n - index: false\n key: c2VuZGVy\n value: aW5qMWN5OHJwNGUyY3ptZjducnN6N2VrcWZmeXp0dnVkOXZ5cm5kem12\n - index: false\n key: YW1vdW50\n value: NDQ2MDE1MDAwMDAwMDAwaW5q\n type: transfer\n- attributes:\n - index: false\n key: c2VuZGVy\n value: aW5qMWN5OHJwNGUyY3ptZjducnN6N2VrcWZmeXp0dnVkOXZ5cm5kem12\n type: message\n- attributes:\n - index: false\n key: ZmVl\n value: NDQ2MDE1MDAwMDAwMDAwaW5q\n type: tx\ngas_used: "89739"\ngas_wanted: "89203"\nheight: "36905"\ninfo: ""\nlogs: []\nraw_log: 'out of gas in location: Has; gasWanted: 89203, gasUsed: 89739: out of gas'\ntimestamp: ""\ntx: null\ntxhash: A52C6EC43D2F277CFA32AD8F9B5BA54D3F52A52ABC70CDB73F2F3155D7A85341\n" batch_size=1 err_code=11 hash=A52C6EC43D2F277CFA32AD8F9B5BA54D3F52A52ABC70CDB73F2F3155D7A85341 svc=oracle timeout=true time="2022-03-22T09:54:08Z" level=warning msg="metrics init failed, will retry in 1 min" error="statsd init failed: dial udp: lookup host.docker.internal: no such host" time="2022-03-22T09:54:15Z" level=info msg="PullPrice (pipeline run) done in 85.853405ms" dynamic=true provider=nftbank-estimates-v2 svc=oracle ticker=BAYC/WETH time="2022-03-22T09:54:18Z" level=info msg="sent Tx in 921.88306ms" batch_size=1 hash=95B3026EE52E4B0AFB73E0960E687638273233F032438C4930E9B4DED49CCA63 svc=oracle timeout=true time="2022-03-22T09:55:08Z" level=warning msg="metrics init failed, will retry in 1 min" error="statsd init failed: dial udp: lookup host.docker.internal: no such host" time="2022-03-22T09:55:15Z" level=info msg="PullPrice (pipeline run) done in 87.577109ms" dynamic=true provider=nftbank-estimates-v2 svc=oracle ticker=BAYC/WETH time="2022-03-22T09:55:19Z" level=info msg="sent Tx in 1.89983051s" batch_size=1 hash=C9F48D77C811E63BD7D6FC2CB3AEE646A32C91B0B99FB8033DE9B7962597CEAC svc=oracle timeout=true

  • HTTP headers spec in task

    HTTP headers spec in task

    Added ability to specify additional HTTP headers, since some price fetching APIs require authorization โ€“ headersMap.

    Usage:

    headersMap="{\\"x-api-key\\": \\"foobar\\"}"
    

    (escaping is needed as it's a JSON mapping inside TOML string)

  • Add some logic to only post transactions if there was a change in the feed

    Add some logic to only post transactions if there was a change in the feed

    Currently the service posts a tx every time it pulls data, the service should keep pulling data every interval and push txs only if there is a difference in the value.

The Oracle Database Operator for Kubernetes (a.k.a. OraOperator) helps developers, DBAs, DevOps and GitOps teams reduce the time and complexity of deploying and managing Oracle Databases

The Oracle Database Operator for Kubernetes (a.k.a. OraOperator) helps developers, DBAs, DevOps and GitOps teams reduce the time and complexity of deploying and managing Oracle Databases. It eliminates the dependency on a human operator or administrator for the majority of database operations.

Dec 14, 2022
Simple online syncing tool for Oracle Object Store

TrollBox ... use your storage with Oracle Object Store Quick Start Make sure you have the Object Storage, bucket and you know the compartment id where

Oct 25, 2021
A seed repository that contains a Go project that accepts input via a REST API and saves data to an Oracle database.

rest-oracle-go-seed A seed repository that contains a Go project that accepts input via a REST API and saves data to an Oracle database. Why Oracle? T

Apr 18, 2022
An Oracle Cloud (OCI) Pulumi resource package, providing multi-language access to OCI

Oracle Cloud Infrastructure Resource Provider The Oracle Cloud Infrastructure (OCI) Resource Provider lets you manage OCI resources. Installing This p

Dec 2, 2022
kubetnl tunnels TCP connections from within a Kubernetes cluster to a cluster-external endpoint, e.g. to your local machine. (the perfect complement to kubectl port-forward)

kubetnl kubetnl (kube tunnel) is a command line utility to tunnel TCP connections from within a Kubernetes to a cluster-external endpoint, e.g. to you

Dec 16, 2022
Traefik-redirect-operator is created to substitute manual effort of creating an ingress and service type External.
Traefik-redirect-operator is created to substitute manual effort of creating an ingress and service type External.

Overview Traefik Redirect Operator is used to help creating a combination of Ingress of Traefik controller along with Service's ExternalName type. The

Sep 22, 2021
A simple multi-layered config loader for Go. Made for smaller projects. No external dependencies.

gocfg โš ๏ธ Work in progress! A simple multi-layered config loader for Go. Made for smaller projects. No external dependencies. Example From main.go: //

Dec 26, 2021
Use cli tool to troubleshoot external API service quickly.
Use cli tool to troubleshoot external API service quickly.

golang CLI Template golang project template for building CLI Setup Setup by Command git clone https://github.com/mpppk/cli-template your_awesome_tool

Jan 5, 2022
Using this you can access node external ip address value from your pod.

Using this you can access node external ip address value from your pod.

Jan 30, 2022