{"id":14958490,"url":"https://github.com/ethereum/ethereum-binaries","last_synced_at":"2025-10-07T11:30:52.599Z","repository":{"id":42837906,"uuid":"264182989","full_name":"ethereum/ethereum-binaries","owner":"ethereum","description":"Fast, easy and secure Ethereum binary management","archived":false,"fork":false,"pushed_at":"2023-03-04T18:22:19.000Z","size":3499,"stargazers_count":20,"open_issues_count":16,"forks_count":10,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-01-15T15:50:01.716Z","etag":null,"topics":["docker","ethereum","geth"],"latest_commit_sha":null,"homepage":"https://ethereum.github.io/ethereum-binaries/#/","language":"TypeScript","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/ethereum.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-15T12:04:04.000Z","updated_at":"2024-11-02T13:48:45.000Z","dependencies_parsed_at":"2024-09-22T07:01:53.726Z","dependency_job_id":"3ac72bdc-bc96-4c08-baf3-10e8c56dad35","html_url":"https://github.com/ethereum/ethereum-binaries","commit_stats":{"total_commits":107,"total_committers":3,"mean_commits":"35.666666666666664","dds":0.01869158878504673,"last_synced_commit":"9ae1349084b2a5e2d1e55949bbea29f9b98722b4"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethereum%2Fethereum-binaries","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethereum%2Fethereum-binaries/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethereum%2Fethereum-binaries/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ethereum%2Fethereum-binaries/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ethereum","download_url":"https://codeload.github.com/ethereum/ethereum-binaries/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235621547,"owners_count":19019520,"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":["docker","ethereum","geth"],"created_at":"2024-09-24T13:17:13.012Z","updated_at":"2025-10-07T11:30:52.082Z","avatar_url":"https://github.com/ethereum.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://circleci.com/gh/ethereum/ethereum-binaries\"\u003e\u003cimg src=\"https://img.shields.io/circleci/project/github/ethereum/ethereum-binaries/master.svg\" alt=\"Build Status\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://npmcharts.com/compare/ethbinary?minimal=true\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/ethbinary.svg\" alt=\"Downloads\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/ethbinary\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/ethbinary.svg\" alt=\"Version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/ethbinary\"\u003e\u003cimg src=\"https://img.shields.io/npm/l/ethbinary.svg\" alt=\"License\"\u003e\u003c/a\u003e\n  \u003cbr\u003e\n\u003c/p\u003e\n\n# Ethereum Binaries\n\n## 🔥 This project has been deprecated and will no longer be maintained. 🔥\n\n\u003cbr/\u003e\n\nFast, easy and secure Ethereum binary management.\n\n- [X] 🎁 **Package Extraction**\n- [x] 🔐 **Binary Verification**\n- [x] ♨️ **Runtime Detection** 🐍\n- [X] 🐳 **Docker Support** \n- [X] ⏰ **Lifecycle Events [ IPC_READY | SYNCED | STOPPED ... ]** \n- [x] ☁️ **Auto Update**\n- [x] ⚡ **Caching**\n- [x] 🐙 **Version Management**\n- [x] 🌈 **Multi Client Support**\n\n# Docs\n\nDocumentation is available at [github.io/ethereum-binaries](https://ethereum.github.io/ethereum-binaries/#/)\n\n# Supported Clients \u0026 Binaries\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\"\u003e\n        \u003cimg align=\"center\" height=\"100\" src=\"https://geth.ethereum.org/static/images/mascot.png\" alt=\"geth logo\"\u003e\n        \u003cbr\u003e\n        \u003ca href=\"https://geth.ethereum.org/\"\u003eGeth\u003c/a\u003e\n      \u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\"\u003e\n        \u003cimg align=\"center\" height=\"100\" src=\"https://prylabs.net/assets/stripedprysm.svg\" alt=\"prysm logo\"\u003e\n        \u003cbr\u003e\n        \u003ca href=\"https://prysmaticlabs.com/\"\u003ePrysm\u003c/a\u003e\n      \u003c/td\u003e\n        \u003ctd align=\"center\" valign=\"top\"\u003e\n        \u003cimg align=\"center\" height=\"100\" src=\"https://avatars0.githubusercontent.com/u/32980830?s=280\u0026v=4\" alt=\"puppeth logo\"\u003e\n        \u003cbr\u003e\n        \u003ca href=\"https://github.com/puppeth\"\u003ePuppeth\u003c/a\u003e\n      \u003c/td\u003e\n      \u003c/td\u003e\n        \u003ctd align=\"center\" valign=\"top\"\u003e\n        \u003cimg align=\"center\" height=\"100\" src=\"https://camo.githubusercontent.com/0f1377ae214406b57e0743067901098502e01d3c/687474703a2f2f7777772e726564616b74696f6e2e74752d6265726c696e2e64652f66696c6561646d696e2f66673330382f69636f6e732f70726f6a656b74652f6c6f676f732f5a6f4b72617465735f6c6f676f2e737667\" alt=\"zokrates logo\"\u003e\n        \u003cbr\u003e\n        \u003ca href=\"https://github.com/Zokrates/ZoKrates\"\u003eZoKrates\u003c/a\u003e\n      \u003c/td\u003e\n     \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Supported clients can be referenced by their name and used directly. For all other binaries see  [`Extension`](#extension)**\n\n# Intro\n\nBinaries are an integral part of the Ethereum ecosystem. There are many amazing tools (Clef, ZoKrates, Puppeth, ...) that go even beyond the different client implementations (Geth, Prysm, Besu, Nethermind, ...).\nHowever, managing them can be a very complex task. There are no standards for how binaries are distributed and you might find Docker images, binaries hosted on (GitHub, Azure, Bintray, AWS), or even have to build them from source yourself by installing the respective toolchains first and learning about language specific details.\nMoreover, important steps such as binary verification with e.g. GPG are often skipped because it is too complex or inconvenient.\nInteracting with these binaries, e.g. from a script file when they are running inside a container creates a whole new set of challenges.\nThe goal of this library is to create a unified interface to download, configure and interact with Ethereum binaries so that it's more about the `what` and less about `how`.\n\n# Installation\n```shell\nnpm install -g ethbinary\n```\n\n# Quickstart 🚀\n\n```shell\nethbinary geth@latest --goerli\n```\n\nWill download the latest version of geth and start geth with a connection to the goerli testnet:\n\n![Fast Start Gif](./img/fast_start.gif?raw=true)\n\n# Examples\n\n## CLI\n```shell\nethbinary list //example: returns [ 'besu', 'ewasm', 'geth', 'prysm' ]\n\nethbinary download geth // will display version selector\nethbinary download geth@1.9.10 // short-hand specifier\nethbinary download geth --clientVersion 1.9.10 // equivalent to above syntax\n\nethbinary exec geth@latest \"version\" // the command MUST be one string for the parser to work\nethbinary exec geth@latest \"account new\" // is auto-attached to terminal so that stdin for password works\nethbinary exec geth --clientVersion latest \"account new\" // verbose syntax\n\nethbinary start geth // will start latest geth version with mainnet connection (geth default)\nethbinary start geth --goerli\nethbinary start geth@1.9.10 --goerli\n```\n\n## Module\n### Minimal Start / Stop\n\n```javascript\nconst { getClient } = require('ethbinary')\nconst geth = await getClient('geth')\nawait geth.start('--goerli')\nawait geth.stop()\n```\n\n### ethers + ethbinary = ❤️\n\n#### Ipc Provider\n\n```javascript\nconst { getClient, CLIENT_STATE  } = require('ethbinary')\nconst ethers = require('ethers')\n\nconst geth = await getClient('geth')\nawait geth.start(['--goerli'])\nawait geth.whenState(CLIENT_STATE.IPC_READY)\nconst provider = new ethers.providers.IpcProvider(geth.ipc)\nconst network = await provider.getNetwork() // network { name: 'goerli', chainId: 5, ensAddress: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e' }\n// send tx, interact with or deploy contracts here...\nawait geth.stop()\n```\n\n#### HTTP RPC Server\n\n```javascript\nconst geth = await getClient('geth')\n// note that --http is new syntax for deprecated --rpc\nawait geth.start(['--dev', '--http'])\nawait geth.whenState(CLIENT_STATE.HTTP_RPC_READY)\nconst provider = new ethers.providers.JsonRpcProvider(geth.rpcUrl)\nconst network = await provider.getNetwork() // network { chainId: 1337, name: 'unknown' }\nawait geth.stop()\n```\n\n### Multi Client API\n\n```javascript\nconst { default: cm } = require('ethbinary') // get the client manager instance\nconst clientId = await cm.getClient('geth')\nawait cm.startClient(clientId, 'latest', ['--goerli'])\nawait cm.stopClient(clientId)\n```\n\n### More Examples\n\ncheck out the other [examples](./examples)\n\n# Binary Types\n\nThere are different types of binaries / programs that all require different implementation and interaction strategies.\nAn attempt to classify them based on interactivity might look like this:\n\n### Services\n\nServices or daemons are binaries that are started as background processes. They usually don't require *interaction*.\n\n`geth` for example can be started as a service. Interaction with the service is happening in this case only via the separate HTTP/IPC RPC API or not at all.\n\n**The interaction pattern is:**\n```javascript\nservice.start()\nservice.whenState(/*rpc ready*/)\n// do something with API\nservice.stop() // optional\n```\n\n### Wizards / Assistants / REPL\n\nWizards are programs that prompt the user interactively for input and perform operations in between those prompts or after they've received a full configuration processing all responses.\nread–eval–print loop (REPL) programs fall into this category because they constantly require user input and perform actions only after interaction.\n\n`puppeth` for example is an interactive wizard.\n\n**The interaction pattern is:**\n\n#### Full user-interaction\n```javascript\nconst puppeth = await getClient('puppeth')\nawait puppeth.start({\n  stdio: 'inherit' // pass control to terminal: user interacts via stdin \u0026 stdout \n})\n```\n\n#### Automation\n```javascript\nconst puppeth = await getClient('puppeth')\nawait puppeth.start()\nawait puppeth.whenState(log =\u003e log.includes('Please specify a network name ')) // parse logs to determine custom state\nawait puppeth.input('my-network-name') // write response to stdin\nawait puppeth.whenState(/*...*/) // wait again\nawait puppeth.input(/*...*/) // respond again\n```\n\n### Servers\n\nPrograms that offer functionality via an API to users or other programs are called `servers` for simplicity.\nThe calling program is called the `client` in the traditional client-server-model. ethbinary takes the `client` role when it is interacting with other programs and performing calls to their API.\n\nThe `ZoKrates` compiler is an example for a program that receives a single command, processes it and returns a result.\n\n**The interaction pattern is:**\n```javascript\nconst zokrates = await getClient('zokrates')\nfs.writeFileSync(path.join(__dirname, 'test.zok'),   `\ndef main(private field a, field b) -\u003e (field):\n  field result = if a * a == b then 1 else 0 fi\n  return result\n`)\nawait zokrates.execute(`compile -i ${SHARED_DATA}/test.zok`) \nawait zokrates.execute(`setup`) \nawait zokrates.execute('compute-witness -a 337 113569') \nawait zokrates.execute('generate-proof') \nawait zokrates.execute(`export-verifier`) \nawait zokrates.execute(`cp ./verifier.sol ${SHARED_DATA}`, { useBash: true, useEntrypoint: false })\n```\nWhere a sequence of commands ins executed with `.execute`\n\n### Hybrid\n\nOf course, some binaries can implement multiple behaviors and act as a service, execute commands and provide server functionality.\n\n`geth` is such an example:\n\n`geth account new` - issues a command which can also be interactive e.g. ask for password\n\n`geth` will start the service\n\n\n# Extension\n\nethbinary was created with extension in mind.\nIf your client is not (yet) supported, chances are good you can still make use of this module and benefit from all of its helpers:\n\nSome ad-hoc integrations will just magically work out of the box (more likely, if your project follows best practices).\n\nSome integrations require a little extra work.\n\nThis is an example how a GitHub hosted binary can be added on the fly in case it's not available:\n\n```typescript\nconst cm = new SingleClientManager()\nconst clientConfig = { \n  name: 'prysm.validator', \n  repository: 'https://github.com/prysmaticlabs/prysm', \n  isPackaged: false,\n  filter: ({ fileName }) =\u003e fileName.includes('validator')\n}\nconst validator = await cm.getClient(clientConfig, {\n  version: '1.0.0-alpha.6',\n})\n```\n\nThis is the same example, written in a rather verbose but detailed style (e.g. during development):\n\n```typescript\nconst cm = new SingleClientManager()\n\n// let's assume prysm is not supported..\n// we add a new (minimal) config first \n// see docs or ./client-plugins for available configurations and properties\ncm.addClientConfig({\n  name: 'prysm.validator',\n  repository: 'github:prysmaticlabs/prysm' // or 'https://github.com/prysmaticlabs/prysm'\n  // dockerimage: 'gcr.io/prysmaticlabs/prysm/validator', // \u003c= if it's a dockerized client\n})\n\n// now, we can already use methods like getClient, getClientVersions etc..\n// most of the time we are done here. but let's try a manual integration\n// prysm binaries are not packaged, but uploaded as raw binaries\n// we opt-out of the packaged binary flow with `packagesOnly: false` and take care of release assets ourselves\n// we will now get all release assets from the prysm github repository, ordered by latest version\nconst versions = await cm.getClientVersions({\n  packagesOnly: false // prysm binaries are not packaged =\u003e return raw assets\n})\n\n// prysm assets contain .sig, .sha256, .exe files among other things\n// if we want the latest binary we can just search e.g. for the first file with .exe or no extension \n// but let's say there is a bug in the .beta.8 so we search for .beta.6\nconst latest = versions.find(release =\u003e {\n  const ext = getFileExtension(release.fileName)\n  const hasBinaryExtension = (ext === undefined || ext === '.exe')\n  return hasBinaryExtension \u0026\u0026 release.fileName.includes('validator') \u0026\u0026 release.version === '1.0.0-alpha.6'\n})\n\n// here, we could check our cache if the binary already exists...\nconst clientPath = `path/to/${latest.fileName}`\n\n// to keep our dependency footprint small we can use the re-exported ethpkg module\n// which is the package manager used internally by ethbinary to manage (find, download, extract, verify...) assets\nconst data = await ethpkg.download(latest.location, onProgress)\nfs.writeFileSync(clientPath, data, {\n  mode: parseInt('754', 8) // make sure binary is executable\n})\n\n// almost done: we create a client instance based on the binary \nconst validator = await cm.getBinaryClient(clientPath)\n\n// that's it - we can now interact with a lifecycle managed binary :tada: \nconst version = await validator.execute(`--version`)\nconst result = await validator.execute(`accounts create -keystore-path \"${__dirname}\" --password=\"${password}\"`)\n// ...\n\n```\n\n# Events\n\nethbinary uses a an event listener mechanism to be notified about the different events during binary preparation.\nMost of the subroutines have 2-3 event(stage)s: `started`, `progress`, `finished`\n\nAn event log for a binary download might look like this:\n```javascript\nresolve_package_started // api request is made + cache is checked\nfetching_release_list_started // api response is processed: json / xml parsing\nfetching_release_list_finished // remote releases are merged with cached releases\nfilter_release_list_started // invalid releases are removed, version + platform info is extracted, custom filter functions are applied\nsort_releases_started // releases are sorted by semver version \u0026 release date\nsort_releases_finished\nfilter_release_list_finished\nresolve_package_finished // the latest release info is available\ndownload_started // the asset for the latest release are downloaded\ndownload_progress\ndownload_finished\nextraction_started // the binary is detected inside the package and the binary or all contents are extracted \nextraction_progreess\nextraction_finished\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fethereum%2Fethereum-binaries","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fethereum%2Fethereum-binaries","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fethereum%2Fethereum-binaries/lists"}