{"id":35216371,"url":"https://github.com/injectivelabs/injective-price-oracle","last_synced_at":"2026-03-11T22:01:32.158Z","repository":{"id":41957397,"uuid":"455344760","full_name":"InjectiveLabs/injective-price-oracle","owner":"InjectiveLabs","description":"Injective's Oracle with dynamic price feeds (for External Integrations)","archived":false,"fork":false,"pushed_at":"2026-01-22T12:58:46.000Z","size":1529,"stargazers_count":7,"open_issues_count":4,"forks_count":7,"subscribers_count":21,"default_branch":"master","last_synced_at":"2026-01-23T04:41:29.604Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/InjectiveLabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-02-03T22:08:46.000Z","updated_at":"2026-01-07T10:08:18.000Z","dependencies_parsed_at":"2026-03-11T22:00:55.749Z","dependency_job_id":null,"html_url":"https://github.com/InjectiveLabs/injective-price-oracle","commit_stats":null,"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"purl":"pkg:github/InjectiveLabs/injective-price-oracle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InjectiveLabs%2Finjective-price-oracle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InjectiveLabs%2Finjective-price-oracle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InjectiveLabs%2Finjective-price-oracle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InjectiveLabs%2Finjective-price-oracle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/InjectiveLabs","download_url":"https://codeload.github.com/InjectiveLabs/injective-price-oracle/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/InjectiveLabs%2Finjective-price-oracle/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30404072,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-11T21:51:19.558Z","status":"ssl_error","status_checked_at":"2026-03-11T21:50:57.892Z","response_time":84,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-29T22:24:49.025Z","updated_at":"2026-03-11T22:01:32.152Z","avatar_url":"https://github.com/InjectiveLabs.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# injective-price-oracle\n\nInjective'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.\n\n## Getting Started\n\nFirst, make sure your Go env is correctly configured, download a distribution from https://go.dev/dl/ the minimum required version is 1.17.\n\nClone this repo:\n\n```bash\ngit clone git@github.com:InjectiveLabs/injective-price-oracle-ext.git\ncd injective-price-oracle-ext\nmake install\n```\n\nAfter binary has been built, it should be available for usage in CLI:\n\n```bash\n$ injective-price-oracle version\n\nVersion dev (77a1017)\nCompiled at 20220203-2207 using Go go1.17.3 (arm64)\n```\n\n## Environment\n\nBefore starting the `injective-price-oracle` service, make sure you copy a template [.env](.env.example) 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.\n\nMore info on private keys: [A Guide to Private Key Management (Oracle)](https://injective.notion.site/A-Guide-to-Private-Key-Management-Oracle-e07fddc2fe7043b5803a97c118dccdcf)\n\n```bash\ncp .env.example .env\n```\n\n## Running with dynamic feeds via binary\n\nThis is an example that loads all dynamic feeds from [examples/](examples/) dir! Make sure to specify correct path to your TOML dir.\n\n```bash\n$ injective-price-oracle start --dynamic-feeds examples\n\n\nINFO[0000] using Cosmos Sender inj128jwakuw3wrq6ye7m4p64wrzc5rfl8tvwzc6s8\nINFO[0000] waiting for GRPC services\nINFO[0001] found 1 dynamic feed configs\nINFO[0001] got 1 enabled price feeds                     svc=oracle\nINFO[0001] initialized 1 price pullers                   svc=oracle\nINFO[0001] starting pullers for 1 feeds                  svc=oracle\nINFO[0007] PullPrice (pipeline run) done in 1.0506275s   dynamic=true provider=binance_v3 svc=oracle ticker=INJ/USDT\nINFO[0014] sent Tx in 2.72982375s                        batch_size=1 hash=1D7D02BDBAEC200BD585E90215459E93C760A1317EFF9D83B822FA4F34AD6A03 svc=oracle timeout=true\nINFO[0067] PullPrice (pipeline run) done in 314.4035ms   dynamic=true provider=binance_v3 svc=oracle ticker=INJ/USDT\nINFO[0073] sent Tx in 1.706471708s                       batch_size=1 hash=6E3A6C8F7706DB0B0355C5691A628A56CD5A87BB14877D2F0D151178FCF2784A svc=oracle timeout=true\nINFO[0128] PullPrice (pipeline run) done in 310.32875ms  dynamic=true provider=binance_v3 svc=oracle ticker=INJ/USDT\nINFO[0133] sent Tx in 1.776902583s                       batch_size=1 hash=29D615079A891F25E5ADE167E78D478F8AA99CEEFED7DB47B3F5E71BFEDEB582 svc=oracle timeout=true\n```\n\n## Running with dynamic feeds via docker-compose\n1. Docker-compose file\n```\nversion: '3.8'\nnetworks:\n  injective:\n    name: injective\nservices:\n  injective-price-oracle:\n    container_name: injective-price-oracle\n    image: public.ecr.aws/l9h3g6c6/injective-price-oracle:prod\n    build: ../../../injective-price-oracle/\n    command: injective-price-oracle start --feeds-dir /root/oracle-feeds\n    logging:\n      driver: journald\n    environment:\n      # log config\n      ORACLE_ENV: prod\n      ORACLE_LOG_LEVEL: info\n      # chain config\n      ORACLE_SERVICE_WAIT_TIMEOUT: \"1m\"\n      ORACLE_COSMOS_CHAIN_ID: injective-1\n      ORACLE_COSMOS_OVERRIDE_NETWORK: \"false\"\n      ORACLE_COSMOS_GRPC: tcp://sentry0.injective.network:9900\n      ORACLE_COSMOS_STREAM_GRPC: tcp://sentry0.injective.network:9999\n      ORACLE_TENDERMINT_RPC: http://sentry0.injective.network:26657\n      ORACLE_COSMOS_GAS_PRICES: 500000000inj\n      ORACLE_COSMOS_GAS_ADJUST: 1.5\n      # keyring config\n      ORACLE_COSMOS_KEYRING: file\n      ORACLE_COSMOS_KEYRING_DIR: /root/keyring-oracle\n      ORACLE_COSMOS_KEYRING_APP: injectived\n      ORACLE_COSMOS_FROM: oracle-user\n      ORACLE_COSMOS_FROM_PASSPHRASE: 12345678\n      ORACLE_COSMOS_PK:\n      ORACLE_COSMOS_USE_LEDGER: \"false\"\n      # You can pass variables from env here into specific integrations,\n      # make sure to suport that in the source code.\n      # ORACLE_BINANCE_URL=\n      # statsd config\n      ORACLE_STATSD_PREFIX: \"inj-oracle\"\n      ORACLE_STATSD_AGENT: \"datadog\"\n      ORACLE_STATSD_ADDR: host.docker.internal:8125\n      ORACLE_STATSD_STUCK_DUR: 5m\n      ORACLE_STATSD_MOCKING: \"false\"\n      ORACLE_STATSD_DISABLED: \"false\"\n    networks:\n      - injective\n    volumes:\n      - ~/keyring-oracle:/root/keyring-oracle\n      - ~/docker-volume/oracle-feeds:/root/oracle-feeds\n```\n2. Start and get logs\n```\ndocker-compose up -d injective-price-oracle\ndocker logs injective-price-oracle\n```\n\n## Adding new feeds\n\nThere are two ways to add new feeds.\n\n### Dynamic feeds (TOML)\n\nMost preferred way is to create **dynamic feeds** using [DOT Syntax](https://en.wikipedia.org/wiki/DOT_(graph_description_language)), using the Chainlink innovation in this area (see [Job Pipelines](https://docs.chain.link/docs/jobs/task-types/pipelines/)).\n\nCheck out this most simple example:\n\n```toml\nprovider = \"binance_v3\"\nticker = \"INJ/USDT\"\npullInterval = \"1m\"\nobservationSource = \"\"\"\n   ticker [type=http method=GET url=\"https://api.binance.com/api/v3/ticker/price?symbol=INJUSDT\"];\n   parsePrice [type=\"jsonparse\" path=\"price\"]\n   multiplyDecimals [type=\"multiply\" times=1]\n\n   ticker -\u003e parsePrice -\u003e multiplyDecimals\n\"\"\"\n```\n\nBeautiful, 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 \u003cdir\u003e`.\n\nSee the full documentation on the supported [Tasks](https://docs.chain.link/docs/tasks/) that you can use.\n\nList of supported pipeline tasks:\n\n* `http` - [docs](https://docs.chain.link/docs/jobs/task-types/http/)🔗\n* `mean` - [docs](https://docs.chain.link/docs/jobs/task-types/mean/)🔗\n* `median` - [docs](https://docs.chain.link/docs/jobs/task-types/median/)🔗\n* `mode` - [docs](https://docs.chain.link/docs/jobs/task-types/mode/)🔗\n* `sum` - [docs](https://docs.chain.link/docs/jobs/task-types/sum/)🔗\n* `multiply` - [docs](https://docs.chain.link/docs/jobs/task-types/multiply/)🔗\n* `divide` - [docs](https://docs.chain.link/docs/jobs/task-types/divide/)🔗\n* `jsonparse` - [docs](https://docs.chain.link/docs/jobs/task-types/jsonparse/)🔗\n* `any` - [docs](https://docs.chain.link/docs/jobs/task-types/any/)🔗\n* `ethabiencode` - [docs](https://docs.chain.link/docs/jobs/task-types/eth-abi-encode/)\n* `ethabiencode2` - [docs](https://github.com/smartcontractkit/chainlink/blob/develop/docs/CHANGELOG.md#enhanced-abi-encoding-support)🔗\n* `ethabidecode` - [docs](https://docs.chain.link/docs/jobs/task-types/eth-abi-decode/)🔗\n* `ethabidecodelog` - [docs](https://docs.chain.link/docs/jobs/task-types/eth-abi-decode-log/)🔗\n* `merge` - [docs](https://github.com/smartcontractkit/chainlink/blob/develop/docs/CHANGELOG.md#merge-task-type)🔗\n* `lowercase`\n* `uppercase`\n\nMore can be added if needed.\n\nList of config fields:\n\n* `provider` - name (or slug) of the used provider, used for logging purposes, ⚠️ needs to be unique across all feed providers.\n* `ticker` - name of the ticker on the Injective Chain. Used for loading feeds for enabled tickers.\n* `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\".\n* `observationSource` - pipeline spec in DOT Syntax\n\nNotes on changes:\n\n* `http` task has been changed from the Chainlink's reference, to skip `allowUnrestrictedNetworkAccess` option, since TOMLs are trusted in this context. Added ability to specify additional HTTP headers, since some price fetching APIs require authorization – `headerMap`. Usage: `headerMap=\"{\\\\\"x-api-key\\\\\": \\\\\"foobar\\\\\"}\"`\n\n#### Probing dynamic feeds\n\nDuring development sometimes one needs to evaluate if his TOML file is correct and the pipeline specification yields a correct result. To avoid running the whole E2E flow with chain, there is a simple stateless command - `probe`!\n\nProbe does the following:\n\n* Loads TOML and parses the pipeline\n* Created a dynamic price feed, as if it was orchestrated in the oracle\n* Tries to pull the price once, using the pipeline\n* Prints the answer or an error\n\nExample:\n\n```\n$ injective-price-oracle probe examples/dynamic_binance.toml\n\nINFO[0000] PullPrice (pipeline run) done in 530.560708ms  dynamic=true provider=binance_v3 svc=oracle ticker=INJ/USDT\nINFO[0000] Answer: 4948000\n```\n\n### Native Go code\n\nYes, 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](/internal/service/oracle/feed_binance.go). Any complex feed can be added as long as the implementation follows this Go interface:\n\n```go\ntype PricePuller interface {\n\tProvider() FeedProvider\n\tProviderName() string\n\tSymbol() string\n\tInterval() time.Duration\n\n\t// PullPrice method must be implemented in order to get a price\n\t// from external source, handled by PricePuller.\n\tPullPrice(ctx context.Context) (price decimal.Decimal, err error)\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finjectivelabs%2Finjective-price-oracle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finjectivelabs%2Finjective-price-oracle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finjectivelabs%2Finjective-price-oracle/lists"}