{"id":18914618,"url":"https://github.com/helium/rosetta-helium","last_synced_at":"2025-07-19T13:32:19.721Z","repository":{"id":38775948,"uuid":"351824771","full_name":"helium/rosetta-helium","owner":"helium","description":"Rosetta implementation for helium","archived":false,"fork":false,"pushed_at":"2022-04-28T15:50:13.000Z","size":10489,"stargazers_count":19,"open_issues_count":20,"forks_count":4,"subscribers_count":21,"default_branch":"main","last_synced_at":"2025-07-14T14:27:01.743Z","etag":null,"topics":["coinbase","helium","helium-blockchain","hnt","rosetta-api"],"latest_commit_sha":null,"homepage":"","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/helium.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-26T15:18:45.000Z","updated_at":"2024-12-03T14:51:23.000Z","dependencies_parsed_at":"2022-09-16T04:30:20.937Z","dependency_job_id":null,"html_url":"https://github.com/helium/rosetta-helium","commit_stats":null,"previous_names":["syuan100/rosetta-helium"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/helium/rosetta-helium","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/helium%2Frosetta-helium","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/helium%2Frosetta-helium/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/helium%2Frosetta-helium/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/helium%2Frosetta-helium/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/helium","download_url":"https://codeload.github.com/helium/rosetta-helium/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/helium%2Frosetta-helium/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265942563,"owners_count":23853294,"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":["coinbase","helium","helium-blockchain","hnt","rosetta-api"],"created_at":"2024-11-08T10:12:14.587Z","updated_at":"2025-07-19T13:32:19.683Z","avatar_url":"https://github.com/helium.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[Read the wiki!](https://github.com/helium/rosetta-helium/wiki)\n\n# Overview\nDockerized [Rosetta API](https://www.rosetta-api.org/) implementation mostly based off of [blockchain-node](https://github.com/helium/blockchain-node):\n- Rosetta specs: [https://www.rosetta-api.org/](rosetta-api.org)\n- This is NOT a full node, but rather works off the latest snapshot as specified in `blockchain-node`. As a result, there is currently no support for historical balances or reconciliation.\n- `blockchain-node` provides the basic blockchain that the Data API reads from\n- `./helium-constructor` implements a simple Express server written in TypeScript exposing [helium-js](https://github.com/helium/helium-js) for Construction API actions (transaction construction, signing mechanisms, etc)\n\nThis project was created by [@syuan100](https://github.com/syuan100) and supported, in part, by the [DeWi Grants Program](https://dewialliance.medium.com/announcing-the-inaugural-dewi-grant-recipients-56b44b9b9b66).\n\n#### See Also\n\n* [Rosetta Community Discussion](https://community.rosetta-api.org/t/helium-network-rosetta-gateway-implementation/529/)\n\n# Quick setup\n\n#### Build container from source\nMainnet:\n```text\nDOCKER_BUILDKIT=1 docker build . -t rosetta-helium:latest\n```\n\nTestnet:\n```text\nDOCKER_BUILDKIT=1 docker build . -t rosetta-helium:latest --build-arg NETWORK=testnet\n```\n\n*Note: `DOCKER_BUILDKIT=1` is not necessary but including it may reduce the image size due to the nature of the conditional build.*\n\n#### Build container using pre-built Helium images\nMainnet:\n```text\nDOCKER_BUILDKIT=1 docker build . -f Dockerfile_quick -t rosetta-helium:latest\n```\n\nTestnet:\n```text\nDOCKER_BUILDKIT=1 docker build . -f Dockerfile_quick -t rosetta-helium:latest --build-arg NETWORK=testnet\n```\n\n#### Run container\nLocal data is stored in `helium-data`\n```text\ndocker run -d --rm --init --ulimit \"nofile=1000000:1000000\" -v \"$(pwd)/helium-data:/data\" -p 8080:8080 -p 44158:44158 rosetta-helium:latest\n```\n\nIt's HIGHLY recommended that you set the internal/external NAT settings through environment variables for better performance:\n\n`NAT_INTERNAL_IP` -\u003e `172.17.0.X` _X depends on how many docker containers you have_\n\n`NAT_INTERNAL_PORT` -\u003e `44158` Default port for peering\n\n`NAT_EXTERNAL_IP` -\u003e Your publicly accessible IP address\n\n`NAT_EXTERNAL_PORT` -\u003e `44158` Generally would want to keep the same port that you exposed in the command line\n\n```text\ndocker run -d --rm --init --ulimit \"nofile=1000000:1000000\" -v \"$(pwd)/helium-data:/data\" -p 8080:8080 -p 44158:44158 -e NAT_INTERNAL_IP={{docker_ip}} -e NAT_INTERNAL_PORT={{docker_port}} -e NAT_EXTERNAL_IP={{public_ip}} -e NAT_EXTERNAL_PORT={{public_port}} rosetta-helium:latest\n```\n\n#### Rosetta CLI check\nMainnet:\n```text\nrosetta-cli check:data --configuration-file rosetta-cli-config/mainnet/config.json\n\nrosetta-cli check:construction --configuration-file rosetta-cli-config/mainnet/config.json\n```\n\nTestnet:\n```text\nrosetta-cli check:data --configuration-file rosetta-cli-config/testnet/config.json\n\nrosetta-cli check:construction --configuration-file rosetta-cli-config/testnet/config.json\n```\n(Please wait a few minutes for the Helium node to initialize before running this command)\n\n[Read more on using the rosetta-cli.](https://github.com/helium/rosetta-helium/wiki/7.-Appendix:-Using-rosetta-cli-for-testing)\n\n# Contributing\nIt's annoying to spin up a docker container for every change that you want to make. So for local development, it is recommended that you run each part of the implementation separately.\n\n### rosetta-helium\n1. Install [golang](https://golang.org/doc/install) if you haven't yet.\n2. At the root directory, run `go run .` to start the rosetta server at port `:8080`\n\n### blockchain-node\n1. Checkout [blockchain-node](https://github.com/helium/blockchain-node/).\n2. Run `make \u0026\u0026 make release` to build a release\n3. Run `make start` to start blockchain-node at port `:4467`\n\n### helium-constructor\n1. Install `node`. I prefer [nvm](https://github.com/nvm-sh/nvm).\n1. `cd helium-constructor`\n2. `npm ci`\n3. `npm run build` or `npm run watch`\n4. `npm run nodemon` to start the express server at port `:3000`\n\nAt this point you should be able to run the `rosetta-cli` check from above and get similiar results to the docker container. Remember, make sure to give `blockchain-node` a few minutes to warm up before it picks up blocks.\n\n# Implementation details\n\n### Supported currencies\n\n- [HNT](https://www.coinbase.com/price/helium) (Helium Token)\n- HST (Helium Security Token)\n\n### Unsupported currencies\n- DC (Data Credits): not implemented as they cannot be actively traded\n\n## Data API transactions\nTransactions support for reading from the Data API\n\n| Transaction | Implemented |\n|----|-----------|\n| `payment_v1` | :white_check_mark: |\n| `payment_v2` | :white_check_mark: |\n| `reward_v1` | :white_check_mark: |\n| `reward_v2` | :white_check_mark: |\n| `security_coinbase_v1` | :white_check_mark: |\n| `security_exchange_v1` | :white_check_mark: |\n| `token_burn_v1` | :white_check_mark: |\n| `transfer_hotspot_v1` | :white_check_mark: |\n| `transfer_hotspot_v2` | :white_check_mark: |\n|  `stake_validator_v1` | :white_check_mark: |\n|  `unstake_validator_v1` | :white_check_mark: |\n|  `transfer_validator_v1` | :white_check_mark: |\n| `create_htlc_v1` | :white_check_mark: |\n|  `redeem_htlc_v1` | :white_check_mark: |\n\n### Fee-only transactions (Only recording implicit_burns for HNT deductions)\n\n| Transaction | Implemented |\n| --- |-----------|\n| `add_gateway_v1` | :white_check_mark: |\n| `assert_location_v1` | :white_check_mark: |\n| `assert_location_v2` | :white_check_mark: |\n| `oui_v1` | :white_check_mark: |\n| `update_gateway_oui_v1` | :white_check_mark: |\n| `routing_v1` | :white_check_mark: |\n| `state_channel_open_v1` | :white_check_mark: |\n\n### Pass-through transactions (No balance changes, only metadata)\n\n| Transaction | Notes |\n|-----|-------|\n| `dc_coinbase_v1` | DC only transaction |\n| `state_channel_close_v1` | DC only transaction |\n| `gen_gateway_v1` | Internal blockchain only |\n| `poc_request_v1` | Internal blockchain only |\n| `poc_receipt_v1` | Internal blockchain only | \n| `consensus_group_v1` | Internal blockchain only |\n| `vars_v1` | Internal blockchain only |\n| `price_oracle_v1` | Oracle HNT value transactions | \n\n## Construction API transactions\nTransaction support for creation via the construction API\n\n| Transaction | Implemented |\n|-----|-----------|\n| `payment_v2` | :white_check_mark: |\n| `security_exchange_v1` | :x: |\n| `create_htlc_v1` | :x: |\n| `redeem_htlc_v1` | :x: |\n| `stake_validator_v1` | :x: |\n| `unstake_validator_v1` | :x: |\n| `transfer_validator_v1` | :x: |\n\n## Additional notes\n### Unstake Transaction Oddities\n\nThe `unstake_validator_v1` transaction is unique in that the balance changing portion of the transaction doesn't happen until the specified cooldown has passed. At that point, there is a callback on the ledger that records the balance change. Unfortunately, there is no way for `blockchain-node` to surface information about this balance change when inspecting a block at a particular height. This is especially important for the rosetta-cli `check:data` command to pass.\n\nTo mitigate this, we decided to store what we are calling \"ghost transactions\" that will be triggered when Rosetta queries a particular block. That way, Rosetta can notice the balance change and properly credit the appropriate account for reconciliation purposes.\n\n**Example:**\n- Unstake transaction dectected at block 5 with a cool down of 10 blocks (transaction fee is deducted here)\n- We store a \"ghost transaction\" in our local BadgerDB at block 15 (current block + cool down) with the appropriate credit to the appropriate account\n- When we query block 15, Rosetta will check BadgerDB for any ghost transactions and include them in the query response.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhelium%2Frosetta-helium","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhelium%2Frosetta-helium","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhelium%2Frosetta-helium/lists"}