{"id":13804994,"url":"https://github.com/keep-starknet-strange/nori","last_synced_at":"2025-07-11T01:32:48.882Z","repository":{"id":220356887,"uuid":"726162872","full_name":"keep-starknet-strange/nori","owner":"keep-starknet-strange","description":"RPC request router and proxy for Starknet, forked from Optimism proxyd.","archived":false,"fork":false,"pushed_at":"2024-02-26T19:12:13.000Z","size":657,"stargazers_count":10,"open_issues_count":6,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-18T21:46:50.893Z","etag":null,"topics":["ethereum","optimism","rpc","starknet"],"latest_commit_sha":null,"homepage":"","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/keep-starknet-strange.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}},"created_at":"2023-12-01T17:05:31.000Z","updated_at":"2024-08-25T06:31:04.000Z","dependencies_parsed_at":"2024-06-21T07:41:55.499Z","dependency_job_id":null,"html_url":"https://github.com/keep-starknet-strange/nori","commit_stats":null,"previous_names":["keep-starknet-strange/nori"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keep-starknet-strange%2Fnori","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keep-starknet-strange%2Fnori/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keep-starknet-strange%2Fnori/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keep-starknet-strange%2Fnori/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/keep-starknet-strange","download_url":"https://codeload.github.com/keep-starknet-strange/nori/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225669684,"owners_count":17505386,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["ethereum","optimism","rpc","starknet"],"created_at":"2024-08-04T01:00:56.127Z","updated_at":"2024-11-21T03:47:39.979Z","avatar_url":"https://github.com/keep-starknet-strange.png","language":"Go","funding_links":[],"categories":["Open-source projects"],"sub_categories":[],"readme":"# Nori\n\nNori (のり) - Derived from \"Norikae\" (乗り換え), meaning transfer or switch, this name reflects the idea of efficiently switching or balancing network requests, akin to a load balancer or router.\n\nIt's essentially a fork of [Optimism proxyd](https://github.com/ethereum-optimism/optimism/tree/develop/proxyd), adapted to work with Starknet.\n\nThis tool implements `nori`, an RPC request router and proxy. It does the following things:\n\n1. Whitelists RPC methods.\n2. Routes RPC methods to groups of backend services.\n3. Automatically retries failed backend requests.\n4. Track backend consensus (`latest`, `safe`, `finalized` blocks), peer count and sync state.\n5. Re-write requests and responses to enforce consensus.\n6. Load balance requests across backend services.\n7. Cache immutable responses from backends.\n8. Provides metrics the measure request latency, error rates, and the like.\n\n\n## Usage\n\nRun `make nori` to build the binary. No additional dependencies are necessary.\n\nTo configure `nori` for use, you'll need to create a configuration file to define your proxy backends and routing rules.  Check out [example.config.toml](./example.config.toml) for how to do this alongside a full list of all options with commentary.\n\nOnce you have a config file, start the daemon via `nori \u003cpath-to-config\u003e.toml`.\n\n\n## Consensus awareness\n\nStarting on v4.0.0, `nori` is aware of the consensus state of its backends. This helps minimize chain reorgs experienced by clients.\n\nTo enable this behavior, you must set `consensus_aware` value to `true` in the backend group.\n\nWhen consensus awareness is enabled, `nori` will poll the backends for their states and resolve a consensus group based on:\n* the common ancestor `latest` block, i.e. if a backend is experiencing a fork, the fork won't be visible to the clients\n* the lowest `safe` block (ACCEPTED_ON_L2 status)\n* the lowest `finalized` block (ACCEPTED_ON_L1 status)\n* peer count\n* sync state\n\nThe backend group then acts as a round-robin load balancer distributing traffic equally across healthy backends in the consensus group, increasing the availability of the proxy.\n\nA backend is considered healthy if it meets the following criteria:\n* not banned\n* avg 1-min moving window error rate ≤ configurable threshold\n* avg 1-min moving window latency ≤ configurable threshold\n* peer count ≥ configurable threshold\n* `latest` block lag ≤ configurable threshold\n* last state update ≤ configurable threshold\n* not currently syncing\n\nWhen a backend is experiencing inconsistent consensus, high error rates or high latency,\nthe backend will be banned for a configurable amount of time (default 5 minutes)\nand won't receive any traffic during this period.\n\n\n## Tag rewrite\n\nWhen consensus awareness is enabled, `nori` will enforce the consensus state transparently for all the clients.\n\nFor example, if a client requests the `starknet_getBlockWithTxs` method with the `latest` tag,\n`nori` will rewrite the request to use the resolved latest block from the consensus group\nand forward it to the backend.\n\nThe following request methods are rewritten:\n* `starknet_call` *\n* `starknet_estimateFee` *\n* `starknet_estimateMessageFee` *\n* `starknet_getBlockTransactionCount` *\n* `starknet_getBlockWithReceipts` *\n* `starknet_getBlockWithTxHashes` *\n* `starknet_getBlockWithTxs` *\n* `starknet_getClass` *\n* `starknet_getClassAt` *\n* `starknet_getClassHashAt` *\n* `starknet_getNonce` *\n* `starknet_getStateUpdate` *\n* `starknet_getStorageAt` *\n* `starknet_getTransactionByBlockIdAndIndex` *\n\n\\* not implemented\n\nAnd `starknet_blockNumber` response is overridden with current block consensus.\n\n\n## Cacheable methods\n\nCache use Redis and can be enabled for the following immutable methods:\n\n* `starknet_chainId`\n* `starknet_getBlockTransactionCount`\n* `starknet_getBlockWithReceipts` (block hash only)\n* `starknet_getBlockWithTxs`\n* `starknet_getTransactionByIdAndIndex`\n\n## Meta method `consensus_getReceipts`\n\u003e Only available after v0.7.0-rc0\n\nTo support backends with different specifications in the same backend group,\nnori exposes a convenient method to fetch receipts abstracting away\nwhat specific backend will serve the request.\n\nEach backend specifies their preferred method to fetch receipts with `consensus_receipts_target` config,\nwhich will be translated from `consensus_getReceipts`.\n\nThis method takes a `blockId` (i.e. `tag|qty|hash`)\nand returns the receipts for all transactions in the block.\n\nRequest example\n```json\n{\n  \"jsonrpc\":\"2.0\",\n  \"id\": 1,\n  \"params\": [{\"block_hash\": \"0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b\"}]\n}\n```\n\nIt currently supports translation to the following targets:\n* `starknet_getBlockWithReceipts(blockId)` (default)\n\nThe selected target is returned in the response, in a wrapped result.\n\nResponse example\n```json\n{\n  \"jsonrpc\": \"2.0\",\n  \"id\": 1,\n  \"result\": {\n    \"method\": \"debug_getRawReceipts\",\n    \"result\": {\n      // the actual raw result from backend\n    }\n  }\n}\n```\n\n## Metrics\n\nSee `metrics.go` for a list of all available metrics.\n\nThe metrics port is configurable via the `metrics.port` and `metrics.host` keys in the config.\n\n## Adding Backend SSL Certificates in Docker\n\nThe Docker image runs on Alpine Linux. If you get SSL errors when connecting to a backend within Docker, you may need to add additional certificates to Alpine's certificate store. To do this, bind mount the certificate bundle into a file in `/usr/local/share/ca-certificates`. The `entrypoint.sh` script will then update the store with whatever is in the `ca-certificates` directory prior to starting `nori`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeep-starknet-strange%2Fnori","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkeep-starknet-strange%2Fnori","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeep-starknet-strange%2Fnori/lists"}