{"id":18114820,"url":"https://github.com/tellor-io/layer","last_synced_at":"2026-02-11T17:07:48.937Z","repository":{"id":195604542,"uuid":"689048784","full_name":"tellor-io/layer","owner":"tellor-io","description":"tellor chain - a cosmos sdk chain for reporting and validating arbitrary data","archived":false,"fork":false,"pushed_at":"2026-01-09T01:06:17.000Z","size":67346,"stargazers_count":52,"open_issues_count":15,"forks_count":13,"subscribers_count":4,"default_branch":"main","last_synced_at":"2026-01-09T07:49:35.273Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.tellor.io","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tellor-io.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":"supported_query_ids_map.json","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":"2023-09-08T17:12:09.000Z","updated_at":"2026-01-08T19:30:53.000Z","dependencies_parsed_at":"2024-02-05T20:27:58.893Z","dependency_job_id":"8c90effa-aefa-4e88-a03f-87d26d5ef390","html_url":"https://github.com/tellor-io/layer","commit_stats":null,"previous_names":["tellor-io/layer"],"tags_count":65,"template":false,"template_full_name":null,"purl":"pkg:github/tellor-io/layer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tellor-io%2Flayer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tellor-io%2Flayer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tellor-io%2Flayer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tellor-io%2Flayer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tellor-io","download_url":"https://codeload.github.com/tellor-io/layer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tellor-io%2Flayer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28642695,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T18:04:35.752Z","status":"ssl_error","status_checked_at":"2026-01-21T18:03:55.054Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: 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":"2024-11-01T03:01:13.032Z","updated_at":"2026-01-21T21:01:51.118Z","avatar_url":"https://github.com/tellor-io.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# Tellor Layer\u003cbr/\u003e\u003cbr/\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/tellor-io/layer/actions/workflows/go.yml\"\u003e\n    \u003cimg src=\"https://github.com/tellor-io/layer/actions/workflows/go.yml/badge.svg\" alt=\"Tests\" /\u003e\n  \u003c/a\u003e\n  \u003ca href='https://twitter.com/WeAreTellor'\u003e\n    \u003cimg src='https://img.shields.io/twitter/url/http/shields.io.svg?style=social' alt='Twitter WeAreTellor' /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n## Overview \u003ca name=\"overview\"\u003e \u003c/a\u003e\n\n\u003cb\u003eTellor Layer\u003c/b\u003e is a stand alone L1 built using the cosmos sdk for the purpose of coming to\nconsensus on any subjective data. It works by using a network of staked parties who are\ncrypto-economically incentivized to honestly report requested data.\n\nFor more in-depth information, checkout the [Tellor Layer tech paper](https://github.com/tellor-io/layer/blob/main/TellorLayer%20-%20tech.pdf) and our [ADRs](https://github.com/tellor-io/layer/tree/main/adr).\n\nFor docs on how to join our public testnet go here:  [https://docs.tellor.io/layer-docs](https://docs.tellor.io/layer-docs)\n\n## Starting a New Chain\n\n1) Select the start script that works for you\n\n- `start_one_node.sh` is for those who want to run a chain with a single validator in a mac environment\n- `start_one_node_aws.sh` is for those who want a chain with a single validator and the option to import a faucet account from a seed phrase to be used in a linux environment\n- `start_two_chains.sh` (mac environment) sets up two nodes/validators and starts one of them from this script. Then to start the other validator you would run the `start_bill.sh` script\n\n2) Run the selected script from the base layer folder:\n\n```sh\n./start_scripts/{selected_script}\n```\n\n## Joining a Running Chain\n\nTo find more information please go to the layer_scripts folder.\n\nHere you will find a detailed breakdown for how to join a chain as a node and how to create a new validator for the chain\n\n## Start a local devnet\n\nRun the chain locally in a docker container, powered by [local-ic](https://github.com/strangelove-ventures/interchaintest/tree/main/local-interchain)\n\nInstall heighliner:\n```sh\nmake get-heighliner\n```\nCreate image:\n```sh\nmake local-image\n```\nInstall local interchain:\n```sh\nmake get-localic\n```\nStart the local-devnet:\n```sh\nmake local-devnet\n```\n\nTo configure the chain (ie add more validators plus more) edit the json in local_devnet/chains/layer.json\n\n\n## Tests\n\nTo run all unit and integration tests:\n\n```go\nmake test\n```\n\nIn addition to the unit and integration tests, there are also end to end tests using the [interchaintest](https://github.com/strangelove-ventures/interchaintest) framework. These tests spin up a live chain with a given number of nodes/validators in docker that you can run transactions and queries against. \n\n[Read more about interchaintests here](e2e/readme.md)\n\n\nRun benchmark tests:\n```sh\nmake bench-report\n```\n\n\n## Linting\n\nTo lint per folder:  \n`make lint-folder-fix FOLDER=\"x/mint\"`\n\nTo lint all files:\n\n`make lint`\n\n## Adding New Getters/Queries\nRead about queries from the Cosmos SDK team [here](https://github.com/cosmos/cosmos-sdk/blob/267b93ee741144c0e6a3d57840a006761d07e6c3/docs/learn/beginner/02-query-lifecycle.md). All nodes do not have to have the same queries. Feel free to make an issue or PR regarding any desired queries to this repo. To add a new query to layer, replace the logic as needed for [`GetCurrentAggregateReport`](https://github.com/tellor-io/layer/blob/5820469f2544b2dc1a34ac06b961b92a4adcb782/x/oracle/keeper/query.go#L46):\n\n1. In `layer/proto/layer/oracle/query.go` , define the rpc endpoint in the `service Query {}` struct. \n```proto\nservice Query {\n  ...\n  // Queries the current aggregate report by query id\n  rpc GetCurrentAggregateReport(QueryGetCurrentAggregateReportRequest) returns (QueryGetCurrentAggregateReportResponse) {\n    option (google.api.http).get = \"/tellor-io/layer/oracle/get_current_aggregate_report/{query_id}\";\n  }\n  ...\n}\n```\n2. Also in `layer/proto/layer/oracle/query.go`, define a Message for the query request and query response. \n\n```proto\n// QueryGetCurrentAggregateReportRequest is the request type for the Query/GetCurrentAggregateReport RPC method.\nmessage QueryGetCurrentAggregateReportRequest {\n  // query_id defines the query id hex string.\n  string query_id = 1;\n}\n// QueryGetCurrentAggregateReportResponse is the response type for the Query/GetCurrentAggregateReport RPC method.\nmessage QueryGetCurrentAggregateReportResponse {\n  // aggregate defines the current aggregate report.\n  Aggregate aggregate = 1;\n  // timestamp defines the timestamp of the aggregate report.\n  uint64 timestamp = 2;\n}\n```\n\n**Note**: When inputting or returning a list of items, use the `repeated` keyword, and optional pagination. Ex. with a different query [here](https://github.com/tellor-io/layer/blob/5820469f2544b2dc1a34ac06b961b92a4adcb782/proto/layer/oracle/query.proto#L329)  \n**Note**: If inputting or returning a custom type, such as `Aggregate`, it needs to be defined and imported within the proto files. Ex [here](https://github.com/tellor-io/layer/blob/5820469f2544b2dc1a34ac06b961b92a4adcb782/proto/layer/oracle/aggregate.proto#L11)\n\n3. Generate the protobuf files for the new query using a custom protoc implementation or `ignite generate proto-go`. (Ignite docs [here](https://github.com/ignite/cli).)\n\n4. Create the query function in layer/x/oracle/keeper/query.go or individual query file. \n```go\n// gets the current aggregate report for a query id\nfunc (k Querier) GetCurrentAggregateReport(ctx context.Context, req *types.QueryGetCurrentAggregateReportRequest) (*types.QueryGetCurrentAggregateReportResponse, error) {\n\tif req == nil {\n\t\treturn nil, status.Error(codes.InvalidArgument, \"invalid request\")\n\t}\n\n\tqueryId, err := hex.DecodeString(req.QueryId)\n\tif err != nil {\n\t\treturn nil, status.Error(codes.InvalidArgument, \"invalid query id\")\n\t}\n\taggregate, timestamp, err := k.keeper.GetCurrentAggregateReport(ctx, queryId)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttimeUnix := timestamp.UnixMilli()\n\n\treturn \u0026types.QueryGetCurrentAggregateReportResponse{\n\t\tAggregate: aggregate,\n\t\tTimestamp: uint64(timeUnix),\n\t}, nil\n}\n```\n\n5. Add test(s) \n\n6. In `layer/x/oracle/autocli.go`, add your query to the `AutoCLIOptions` return  \n\n```go\nfunc (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions {\n\treturn \u0026autocliv1.ModuleOptions{\n\t\tQuery: \u0026autocliv1.ServiceCommandDescriptor{\n\t\t\tService: modulev1.Query_ServiceDesc.ServiceName,\n\t\t\tRpcCommandOptions: []*autocliv1.RpcCommandOptions{\n        ...\n\t\t\t\t{\n\t\t\t\t\tRpcMethod:      \"GetCurrentAggregateReport\",\n\t\t\t\t\tUse:            \"get-current-aggregate-report [query_id]\",\n\t\t\t\t\tShort:          \"Query current aggregate report\",\n\t\t\t\t\tPositionalArgs: []*autocliv1.PositionalArgDescriptor{{ProtoField: \"query_id\"}},\n\t\t\t\t},\n        ...\n      }\n    }\n  }\n  ...\n}\n```\n\n7. Run `./scripts/protoc-swagger-gen.sh ` to generate the swagger page documentation\n\n### Using pagination\nSome queries return very long lists from storage. To only retrieve what you need, you can use pagination. \nAt the end of a query command, you can add:\n- `--page-limit n` to only return n results\n- `--page-reverse` to retreive the keys in descending order\n- `--page-count-total` to see the total number of results returned\n\nFor example, if you wanted to only return the most recent 10 reports for a certain reporter, you can use:\n```bash\n./layerd query oracle get-reportsby-reporter $REP_ADDR --page-limit 10 --page-reverse\n```\n\n## Maintainers\u003ca name=\"maintainers\"\u003e \u003c/a\u003e\n\nThis repository is maintained by the [Tellor team](https://github.com/orgs/tellor-io/people)\n\n## How to Contribute\u003ca name=\"how2contribute\"\u003e \u003c/a\u003e  \n\nCheck out our issues log here on Github or feel free to reach out anytime [info@tellor.io](mailto:info@tellor.io)\n\n## Community\u003ca name=\"community\"\u003e \u003c/a\u003e  \n\n- [Official Website](https://tellor.io/)\n- [Discord](https://discord.gg/n7drGjh)\n- [Twitter](https://twitter.com/wearetellor)\n\n## Copyright\u003ca name=\"copyright\"\u003e \u003c/a\u003e  \n\nTellor Inc. 2025\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftellor-io%2Flayer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftellor-io%2Flayer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftellor-io%2Flayer/lists"}