{"id":15043164,"url":"https://github.com/ether1project/ethofs-sdk","last_synced_at":"2025-08-01T23:30:47.421Z","repository":{"id":43085118,"uuid":"317962685","full_name":"Ether1Project/ethofs-sdk","owner":"Ether1Project","description":null,"archived":false,"fork":false,"pushed_at":"2022-07-29T20:16:43.000Z","size":86626,"stargazers_count":1,"open_issues_count":0,"forks_count":3,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-07-28T02:18:22.448Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/Ether1Project.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}},"created_at":"2020-12-02T18:59:47.000Z","updated_at":"2022-03-19T18:01:37.000Z","dependencies_parsed_at":"2022-09-19T20:43:22.160Z","dependency_job_id":null,"html_url":"https://github.com/Ether1Project/ethofs-sdk","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Ether1Project/ethofs-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ether1Project%2Fethofs-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ether1Project%2Fethofs-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ether1Project%2Fethofs-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ether1Project%2Fethofs-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ether1Project","download_url":"https://codeload.github.com/Ether1Project/ethofs-sdk/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ether1Project%2Fethofs-sdk/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268311093,"owners_count":24230273,"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","status":"online","status_checked_at":"2025-08-01T02:00:08.611Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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-09-24T20:48:39.296Z","updated_at":"2025-08-01T23:30:46.087Z","avatar_url":"https://github.com/Ether1Project.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv class=\"bg-gray-dark\"\u003e\n\u003cimg src=\"https://github.com/Ether1Project/Ether-1-Branding/raw/master/PNG%20Logos/ethoProtocolBlack.png\" width=\"200\" /\u003e\n\u003c/div\u003e\n\n# Etho Protocol SDK\n\nOfficial NodeJS SDK for [Etho Protocol](https://ethoprotocol.com)\n\n## Overview\n\nThe Etho Protocol NodeJS SDK provides the quickest / easiest path for interacting with the [Etho Protocol Network](https://docs.ethoprotocol.com/ethofs/ethofs-introduction).\n\n## Installation\n```\nnpm install --save @ethoprotocol/sdk\n```\n\n## Setup\nTo start, simply require the ethoFS SDK and set up an instance with your ethoFS Upload Address/Key (Etho Protocol Key). Register a new upload address using the addUser function or by registering at: [Etho Protocol Uploads](https://uploads.ethoprotocol.com).\n\n## Initialization Without Authentication\n```javascript\nconst ethofsSDK = require('@ethoprotocol/sdk');\nconst ethofs = ethofsSDK();\n```\n## Initialization With Authentication\n```javascript\nconst ethofsSDK = require('@ethoprotocol/sdk');\nconst ethofs = ethofsSDK('yourETHOPrivateKey');\n```\n## Initialization With Custom RPC/Gateway Locations\n##### Params\n* `connections` : A JSON object that contains the following keyvalues:\n  * `rpc` (optional) : The Etho Protocol RPC Location\n  * `gateway` (optional) : The IPFS API/Gateway Location\n##### Example Code\n```javascript\nconst connections = {\n    rpc: 'https://rpc.ethoprotocol.com',\n    gateway: 'https://gateway.ethoprotocol.com'\n};\nconst ethofsSDK = require('@ethoprotocol/sdk');\nconst ethofs = ethofsSDK('yourETHOPrivateKey', connections);\n```\n\nQuickly test that you can connect to the API with the following call:\n```javascript\nethofs.testAuthentication().then((result) =\u003e {\n    //handle successful authentication here\n    console.log(result);\n}).catch((err) =\u003e {\n    //handle error here\n    console.log(err);\n});\n```\n## Usage\nOnce you've set up your instance, using the ethoFS SDK is easy. Simply call your desired function and handle the results of the promise.\n\n## Authentication Not Required (ethoFS key not required on initialization)\n* Data\n  * [networkStats](#networkStats-anchor)\n  * [nodeLocations](#nodeLocations-anchor)\n  * [calculateCost](#calculateCost-anchor)\n\n## Authentication Required (ethoFS key required on initialization)\n* User\n  * [addUser](#addUser-anchor)\n* Pinning\n  * [pinFileToIPFS](#pinFileToIPFS-anchor)\n  * [pinFolderToIPFS](#pinFolderToIPFS-anchor)\n  * [pinFromFS](#pinFromFS-anchor)\n  * [extendPin](#extendPin-anchor)\n  * [unpin](#unpin-anchor)\n\n* Data\n  * [testAuthentication](#testAuthentication-anchor)\n  * [pinList](#pinList-anchor)\n\u003cbr /\u003e\n\u003ca name=\"networkStats-anchor\"\u003e\u003c/a\u003e\n### `networkStats`\nRetrieve ethoFS Network Stats.\n\n##### `ethofs.networkStats()`\n##### Params\n\n#### Response\n```\n{\n    activeUploadContracts: This is number of active upload contracts on the network,\n    totalNetworkStorageUse: This is total used storage space(in bytes) used on the network,\n    networkStorageAvailable: This is total used storage space(in bytes) available on the network,\n    active_gatewaynodes: This is total number of active Gateway Nodes on the network,\n    active_masternodes: This is total number of active Masternodes on the network,\n    active_servicenodes: This is total number of active Service Nodes on the network,\n    gatewaynode_reward: This is the previous daily reward payment for Gateway Nodes,\n    masternode_reward: This is the previous daily reward payment for Masternodes,\n    servicenode_reward: This is the previous daily reward payment for Service Nodes\n}\n```\n##### Example Code\n```javascript\nethofs.networkStats().then((result) =\u003e {\n    //handle results here\n    console.log(result);\n}).catch((err) =\u003e {\n    //handle error here\n    console.log(err);\n});\n```\n\u003ca name=\"nodeLocations-anchor\"\u003e\u003c/a\u003e\n### `nodeLocations`\nRetrieve Etho Protocol Node Location Information.\n\n##### `ethofs.nodeLocations()`\n##### Params\n\n#### Response Array\n```\n[\n    {\n        type: This is type of node (Gateway Node, Masternode, Service Node),\n        id: This is the unique node id,\n        latitude: This is the latitude of node (geolocated by IP address),\n        longitude: This is the longitude of node (geolocated by IP address)\n    }\n]\n```\n##### Example Code\n```javascript\nethofs.nodeLocations().then((result) =\u003e {\n    //handle results here\n    console.log(result);\n}).catch((err) =\u003e {\n    //handle error here\n    console.log(err);\n});\n```\n\u003ca name=\"calculateCost-anchor\"\u003e\u003c/a\u003e\n### `calculateCost`\nEstimate cost of a data upload by sending a request with upload duration and estimated size.\n\n##### `ethofs.calculateCost(options)`\n##### Params\n* `readableStream` - A [readableStream](https://nodejs.org/api/stream.html) of the file to be added \n* `options` : A JSON object that contains the following keyvalues:\n  * `ethofsOptions` : A JSON object with additional [options](#ethofsData-anchor) for the data being pinned\n#### Response\n```\n{\n    uploadSize: This is the calculated size of the upload,\n    uploadDuration: This is the upload contract duration provided by the user,\n    uploadCost: This is the calculated total cost in ETHO (wei) for the upload\n}\n```\n##### Example Code\n```javascript\nconst fs = require('fs');\nconst readableStreamForFile = fs.createReadStream('./yourfile.png');\nconst options = {\n    ethofsOptions: {\n        hostingContractDuration: 100000,\n        hostingContractSize: 20000000\n    }\n};\nethofs.calculateCost(options).then((result) =\u003e {\n    //handle results here\n    console.log(result);\n}).catch((err) =\u003e {\n    //handle error here\n    console.log(err);\n});\n```\n\u003ca name=\"addUser-anchor\"\u003e\u003c/a\u003e\n### `addUser`\nAdd a new user/address to ethoFS network.\n\n##### `ethofs.addUser(userName)`\n##### Params\n* `userName` - A string of the desired user name for ethoFS registration\n#### Response\n```\n{\n    ethoTXHash: This is transaction hash of the confirmed upload contract on the Ether-1 Network\n}\n```\n##### Example Code\n```javascript\nvar userName = 'TestUserName';\n\nethofs.addUser(userName).then((result) =\u003e {\n    //handle results here\n    console.log(result);\n}).catch((err) =\u003e {\n    //handle error here\n    console.log(err);\n});\n```\n\u003ca name=\"pinFileToIPFS-anchor\"\u003e\u003c/a\u003e\n### `pinFileToIPFS`\nSend a file to ethoFS for direct pinning to IPFS.\n\n##### `ethofs.pinFileToIPFS(readableStream, options)`\n##### Params\n* `readableStream` - A [readableStream](https://nodejs.org/api/stream.html) of the file to be added \n* `options` : A JSON object that contains the following keyvalues:\n  * `ethofsData` : A JSON object with (#ethofsData-anchor) for the data being pinned\n  * `ethofsOptions` : A JSON object with additional [options](#ethofsData-anchor) for the data being pinned\n#### Response\n```\n{\n    ipfsHash: This is the IPFS multi-hash provided back for your content,\n    ethoTXHash: This is transaction hash of the confirmed upload contract on the Ether-1 Network,\n    uploadCost: This is the total cost in ETHO for the upload,\n    initiationBlock: This is the block number the upload contract was initialized/created on,\n    expirationBlock: This is the block number that the upload contract will expire on\n}\n```\n##### Example Code\n```javascript\nconst fs = require('fs');\nconst readableStreamForFile = fs.createReadStream('./yourfile.png');\nconst options = {\n    ethofsData: {\n        name: 'MyCustomUploadName',\n        keyvalues: {\n            customKey: 'customValue',\n            customKey2: 'customValue2'\n        }\n    },\n    ethofsOptions: {\n        hostingContractDuration: 100000\n    }\n};\nethofs.pinFileToIPFS(readableStreamForFile, options).then((result) =\u003e {\n    //handle results here\n    console.log(result);\n}).catch((err) =\u003e {\n    //handle error here\n    console.log(err);\n});\n```\n\u003ca name=\"pinFolderToIPFS-anchor\"\u003e\u003c/a\u003e\n### `pinFolderToIPFS`\nSend a folder to ethoFS for direct pinning to IPFS.\n\n##### `ethofs.pinFolderToIPFS(readableStream, options)`\n##### Params\n* `readableStream` - A [readableStream](https://nodejs.org/api/stream.html) of the folder to be added \n* `options` : A JSON object that contains the following keyvalues:\n  * `ethofsData` : A JSON object with (#ethofsData-anchor) for the data being pinned\n  * `ethofsOptions` : A JSON object with additional [options](#ethofsData-anchor) for the data being pinned\n#### Response\n```\n{\n    ipfsHash: This is the IPFS multi-hash provided back for your content,\n    ethoTXHash: This is transaction hash of the confirmed upload contract on the Ether-1 Network,\n    uploadCost: This is the total cost in ETHO for the upload,\n    initiationBlock: This is the block number the upload contract was initialized/created on,\n    expirationBlock: This is the block number that the upload contract will expire on\n}\n```\n##### Example Code\n```javascript\nconst fs = require('fs');\nconst readableStreamForFolder = fs.createReadStream('./yourDirectory');\nconst options = {\n    ethofsData: {\n        name: 'MyCustomUploadName',\n        keyvalues: {\n            customKey: 'customValue',\n            customKey2: 'customValue2'\n        }\n    },\n    ethofsOptions: {\n        hostingContractDuration: 100000\n    }\n};\nethofs.pinFolderToIPFS(readableStreamForFolder, options).then((result) =\u003e {\n    //handle results here\n    console.log(result);\n}).catch((err) =\u003e {\n    //handle error here\n    console.log(err);\n});\n```\n\u003ca name=\"pinFromFS-anchor\"\u003e\u003c/a\u003e\n### `pinFromFS`\nSend a file/directory from local filesystem to ethoFS for direct pinning to IPFS.\n\n##### `ethofs.pinFromFS(fsLocation, options)`\n##### Params\n* `fsLocation` - A local filesystem location of the file or directory to be added \n* `options` : A JSON object that contains the following keyvalues:\n  * `ethofsData` : A JSON object with (#ethofsData-anchor) for the data being pinned\n  * `ethofsOptions` : A JSON object with additional [options](#ethofsData-anchor) for the data being pinned\n#### Response\n```\n{\n    ipfsHash: This is the IPFS multi-hash provided back for your content,\n    ethoTXHash: This is transaction hash of the confirmed upload contract on the Ether-1 Network,\n    uploadCost: This is the total cost in ETHO for the upload,\n    initiationBlock: This is the block number the upload contract was initialized/created on,\n    expirationBlock: This is the block number that the upload contract will expire on\n}\n```\n##### Example Code\n```javascript\nconst sourceDirectory = ('./yourDirectory');\nconst options = {\n    ethofsData: {\n        name: 'MyCustomDirectoryUploadName',\n        keyvalues: {\n            customKey: 'customValue',\n            customKey2: 'customValue2'\n        }\n    },\n    ethofsOptions: {\n        hostingContractDuration: 100000\n    }\n};\nethofs.pinFromFS(sourceDirectory, options).then((result) =\u003e {\n    //handle results here\n    console.log(result);\n}).catch((err) =\u003e {\n    //handle error here\n    console.log(err);\n});\n```\n\u003ca name=\"extendPin-anchor\"\u003e\u003c/a\u003e\n### `extendPin`\nHave ethoFS extend content that you've pinned/uploaded through the platform.\n\n##### `ethofs.extendPin(uploadContractAddress, options)`\n##### Params\n* `uploadContractAddress` - the upload contract address of the content you wish to remove from ethoFS\n* `options` : A JSON object that contains the following keyvalues:\n  * `ethofsOptions` : A JSON object with (#ethofsOptions-anchor) for the data being extended\n#### Response\n```\n{\n    ethoTXHash: This is transaction hash of the confirmed upload contract extension on the Ether-1 Network\n}\n```\n##### Example Code\n```javascript\nconst options = {\n    ethofsOptions: {\n        hostingContractDuration: 100000\n    }\n};\nethofs.extendPin(hostingContractAddress, options).then((result) =\u003e {\n    //handle results here\n    console.log(result);\n}).catch((err) =\u003e {\n    //handle error here\n    console.log(err);\n});\n```\n\u003ca name=\"unpin-anchor\"\u003e\u003c/a\u003e\n### `unpin`\nHave ethoFS unpin content that you've pinned/uploaded through the platform.\n\n##### `ethofs.unpin(uploadContractAddress)`\n##### Params\n* `uploadContractAddress` - the upload contract address of the content you wish to remove from ethoFS\n#### Response\n```\n{\n    ethoTXHash: This is transaction hash of the confirmed upload contract removal on the Ether-1 Network\n}\n```\n##### Example Code\n```javascript\nethofs.unpin(hashToUnpin).then((result) =\u003e {\n    //handle results here\n    console.log(result);\n}).catch((err) =\u003e {\n    //handle error here\n    console.log(err);\n});\n```\n\n\u003ca name=\"testAuthentication-anchor\"\u003e\u003c/a\u003e\n### `testAuthentication`\nTests that you can authenticate with ethoFS correctly and the authentication key is registered\n\n##### `ethofs.testAuthentication()`\n##### Params\nNone\n\n#### Response\n```\n{\n    authenticated: true\n}\n```\n\n##### Example Code\n```javascript\nethofs.testAuthentication().then((result) =\u003e {\n    //handle results here\n    console.log(result);\n}).catch((err) =\u003e {\n    //handle error here\n    console.log(err);\n});\n```\n\u003ca name=\"pinList-anchor\"\u003e\u003c/a\u003e\n### `pinList`\nList pin contracts stored in ethoFS.\n\n##### `ethofs.pinList(options)`\n##### Params\n* `options` (optional) : A JSON object that contains the following keyvalues:\n  * `ethofsDataFilter` (optional) : A JSON object with (#ethofsDataFilter-anchor) for the filtering out pinned data\n#### Response\n```\n{\n    address: This is the Ether-1 contract address,\n    data: This is any saved data along with upload (ie name/keyvalues),\n    ipfsHash: This is the IPFS multi-hash provided back for your content,\n    initiationBlock: This is the original Ether-1 block the upload was iniated/recorded in,\n    expirationBlock: This is the Ether-1 expiration block of the upload contract\n}\n```\n##### Example Code\n```javascript\nconst options = {\n    ethofsDataFilter: {\n        name: 'MyNameFilter',\n        keyvalues: {\n            customKeyFilter: 'customValueFilter',\n            customKey2Filter: 'customValue2Filter'\n        }\n    },\n};\nethofs.pinList(options).then((result) =\u003e {\n    //handle results here\n    console.log(result);\n}).catch((err) =\u003e {\n    //handle error here\n    console.log(err);\n});\n```\n\n\u003ca name=\"ethofsOptions-anchor\"\u003e\u003c/a\u003e\n\n## ethoFS Options\nSome endpoints allow you to pass additional options for ethoFS to take into account when adding content to IPFS.\n\nThe options object can consist of the following values:\n* uploadContractDuration (required) - The duration in ETHO blocks you would like your upload pinned for. A minimum of 100000 blocks is required.\n\n##### Example ethofsOptions object\n```\n{\n    hostingContractDuration: 100000\n}\n```\n\u003ca name=\"ethofsData-anchor\"\u003e\u003c/a\u003e\n\n## ethoFS Data\nSome endpoints allow you to pass additional data to store with your IPFS upload.\n\nThe options object can consist of the following values:\n* name (optional) - The name of your upload.\n* keyvalues (optional) - Misc metadata to store with your upload.\n\n##### Example ethofsData object\n```\n{\n    name: 'UploadContractName',\n    keyvalues: {\n        customKey: 'customValue',\n        customKey2: 'customValue2'\n    }\n}\n```\n\n\u003ca name=\"ethofsDataFilter-anchor\"\u003e\u003c/a\u003e\n\n## ethoFS Data Filter\nSome endpoints allow you to pass additional data filters to filter out existing contracts.\n\nThe options object can consist of the following values:\n* name (optional) - The name of your upload.\n* keyvalues (optional) - Misc metadata stored with your upload.\n\n##### Example ethofsDataFilter object\n```\n{\n    name: 'UploadContractNameFilter',\n    keyvalues: {\n        customKeyFilter: 'customValueFilter',\n        customKey2Filter: 'customValue2Filter'\n    }\n}\n```\n\n## Questions? Issues? Suggestions? \nFeel free to file a github issue or email us at admin@ethoprotocol.com\n\nWe'd love to hear from you!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fether1project%2Fethofs-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fether1project%2Fethofs-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fether1project%2Fethofs-sdk/lists"}