{"id":13565623,"url":"https://github.com/ipfs-shipyard/ipfs-provider","last_synced_at":"2025-04-26T02:33:49.807Z","repository":{"id":34923156,"uuid":"190032941","full_name":"ipfs-shipyard/ipfs-provider","owner":"ipfs-shipyard","description":"Connect to IPFS via an available provider","archived":false,"fork":false,"pushed_at":"2023-03-04T03:51:36.000Z","size":2619,"stargazers_count":33,"open_issues_count":8,"forks_count":6,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-04-18T05:46:05.948Z","etag":null,"topics":["ipfs","p2p","provider"],"latest_commit_sha":null,"homepage":"","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/ipfs-shipyard.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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}},"created_at":"2019-06-03T15:31:25.000Z","updated_at":"2024-05-30T10:38:37.000Z","dependencies_parsed_at":"2024-01-16T18:59:37.929Z","dependency_job_id":"99baf165-14ed-49f2-bb3e-28e551068c66","html_url":"https://github.com/ipfs-shipyard/ipfs-provider","commit_stats":{"total_commits":44,"total_committers":4,"mean_commits":11.0,"dds":0.4772727272727273,"last_synced_commit":"4bde75366e79799c330c63a6c4ed96746402aca1"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipfs-shipyard%2Fipfs-provider","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipfs-shipyard%2Fipfs-provider/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipfs-shipyard%2Fipfs-provider/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipfs-shipyard%2Fipfs-provider/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ipfs-shipyard","download_url":"https://codeload.github.com/ipfs-shipyard/ipfs-provider/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250922195,"owners_count":21508289,"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":["ipfs","p2p","provider"],"created_at":"2024-08-01T13:01:51.366Z","updated_at":"2025-04-26T02:33:49.471Z","avatar_url":"https://github.com/ipfs-shipyard.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# ipfs-provider\n\n[![](https://img.shields.io/github/release/ipfs-shipyard/ipfs-provider.svg)](https://github.com/ipfs-shipyard/ipfs-provider/releases/latest)\n[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai)\n[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/)\n[![Build Status](https://flat.badgen.net/travis/ipfs-shipyard/ipfs-provider)](https://travis-ci.com/ipfs-shipyard/ipfs-provider)\n[![Dependency Status](https://david-dm.org/ipfs-shipyard/ipfs-provider.svg?style=flat-square)](https://david-dm.org/ipfs-shipyard/ipfs-provider)\n\n\u003e Returns IPFS API object by trying multiple [providers](#providers) in a custom fallback order.\n\u003e\n\u003e This is a general-purpose replacement for [ipfs-redux-bundle](https://github.com/ipfs-shipyard/ipfs-redux-bundle).\n\n- [Install](#install)\n- [Usage](#usage)\n- [Examples](#examples)\n- [Providers](#providers)\n  - [`httpClient`](#httpclient) (remote/local HTTP API)\n  - [`jsIpfs`](#jsipfs) (embedded js-ipfs node)\n\u003c!-- TODO: improve this API  - [create our own!](#creating-a-provider) --\u003e\n- [Test](#test)\n\n\n## Install\n\n### via NPM\n\n```console\n$ npm install ipfs-provider\n```\n\n### via prebuilt browser bundles\n\n```html\n\u003c!-- remember to include js-ipfs (core) and/or js-ipfs-http-client, if they are used --\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/ipfs-core/dist/index.min.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/ipfs-http-client/dist/index.min.js\"\u003e\u003c/script\u003e\n\n\u003c!-- prebuilt and minified bundle --\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/ipfs-provider/dist/index.min.js\"\u003e\u003c/script\u003e\n\n\u003cscript\u003e\n  const { getIpfs, providers } = window.IpfsProvider\n  const { ipfs, provider, apiAddress } = await getIpfs({\n    loadHttpClientModule: () =\u003e window.IpfsHttpClient,\n    loadJsIpfsModule: () =\u003e window.IpfsCore,\n    providers: [ /* see Usage below */ ]\n    })\n\u003c/script\u003e\n```\n\n**Note:** when using prebuilt bundles in production use explicit versions and SRI hashes.\nDetails [here](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs-http-client#in-a-web-browser).\n\u003c!-- TODO: add prebuild+versions+sri example to ./examples --\u003e\n\n## Usage\n\n```js\nconst { getIpfs, providers } = require('ipfs-provider')\nconst { httpClient, jsIpfs } = providers\n\nconst { ipfs, provider, apiAddress } = await getIpfs({\n  // when httpClient provider is used multiple times\n  // define its constructor once, at the top level\n  loadHttpClientModule: () =\u003e require('ipfs-http-client'),\n\n  // note this is an array, providers are tried in order:\n  providers: [\n\n    // try various HTTP endpoints (best-effort),\n    httpClient({\n      // (1) try multiaddr of a local node\n      apiAddress: '/ip4/127.0.0.1/tcp/5001'\n    }),\n    httpClient(), // (2) try \"/api/v0/\" on the same Origin as the page\n    httpClient({\n      // (3) try arbitrary API from URL string\n      apiAddress: 'https://some.example.com:8080'\n    }),\n    httpClient({\n      // (4) try API defined by a custom http client config\n      apiAddress: {\n        host: 'apis.example.com',\n        port: '443',\n        protocol: 'https',\n        apiPath: 'custom/path/to/api/v0',\n        headers: {\n          authorization: 'Basic dXNlcjpwYXNz'\n        }\n      }\n    }),\n    // (5) final fallback to spawning embedded js-ipfs running in-page\n    jsIpfs({\n      // js-ipfs package is used only once, as a last resort\n      loadJsIpfsModule: () =\u003e require('ipfs-core'),\n      options: { } // pass config: https://github.com/ipfs/js-ipfs/blob/master/packages/ipfs/docs/MODULE.md#ipfscreateoptions\n    })\n  ]\n})\n\nfor await (const file of ipfs.add(\"text\")) {\n  if (file \u0026\u0026 file.cid) {\n    console.log(`successfully stored at ${file.cid}`)\n  } else {\n    console.error('unable to ipfs.add', file)\n  }\n}\n```\n\n- `ipfs` – returned instance of IPFS API (see [SPEC](https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/README.md))\n- `provider` – a string with a name of the first successful provider.\n   - built-in names match constants from `providers`: `httpClient`, `jsIpfs`, `windowIpfs` and `webExt`.\n- `apiAddress` – returned only when `httpClient` provider is used, provides information which HTTP endpoint succeded\n\n\n## Examples\n\nSee [`examples/`](./examples) for sample code and demonstration of advanced fallback strategies.\n\n## Providers\n\nYou can customize the order of the providers by passing a different array order to the `providers` array.\n\n\nFor example, if you want to try `httpClient` and then `jsIpfs`, you should run it like this:\n\n```js\nconst { getIpfs, providers } = require('ipfs-provider')\nconst { httpClient, jsIpfs } = providers\n\nconst { ipfs, provider } = await getIpfs({\n  providers: [\n    httpClient(),\n    jsIpfs()\n  ]\n})\n```\n\n#### Customizing connection test\n\n```js\nconst { ipfs, provider } = await getIpfs({\n  providers: [ /* array of providers to try in order */ ],\n  connectionTest: () =\u003e { /* boolean function to test the connection to IPFS, default one tries to ipfs.get the CID of an empty directory */ },\n})\n```\n\n### `httpClient`\n\nTries to connect to HTTP API via [`js-ipfs-http-client`](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs-http-client):\n\n```js\nconst { ipfs, provider } = await getIpfs({\n  providers: [\n    httpClient({\n      loadHttpClientModule: () =\u003e require('ipfs-http-client'),\n      apiAddress: 'https://api.example.com:8080/'\n    })\n  ]\n})\n```\n\nThis provider will attempt to establish connection with (in order):\n1. `apiAddress` (if provided)\n2. `/api/` at the current Origin\n3. the default local API (`/ip4/127.0.0.1/tcp/5001`)\n\nIt supports lazy-loading and small bundle sizes. The client library is initialized using constructor (in order):\n1. one returned by `loadHttpClientModule` async function (if provided)\n2. one exposed at `window.IpfsHttpClient` (if present)\n\nValue passed in `apiAddress` can be:\n- a multiaddr (string like `/ip4/127.0.0.1/tcp/5001` or an [object](https://github.com/multiformats/js-multiaddr/))\n- a String with an URL (`https://api.example.com:8080/`)\n- a configuration object supported by the [constructor](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs-http-client#importing-the-module-and-usage)\n  (`{ host: '1.1.1.1', port: '80', apiPath: '/ipfs/api/v0' }`)\n\n\nTo try multiple endpoints, simply use this provider multiple times.\nSee [`examples/browser-browserify/src/index.js`](./examples/browser-browserify/src/index.js) for real world example.\n\n### `jsIpfs`\n\nSpawns embedded [`js-ipfs`](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs) (a full IPFS node in JavaScript)\nin the context of the current page using customizable constructor:\n\n```js\nconst { ipfs, provider } = await getIpfs({\n  providers: [\n    jsIpfs({\n      loadJsIpfsModule: () =\u003e require('ipfs-core'),\n      options: { /* advanced config */ }\n    })\n  ]\n})\n```\n\n- `loadJsIpfsModule` should be a function that returns a promise that resolves to a js-ipfs constructor\n   \u003c!-- TODO confirm below is true, if it is, add example to examples/ and link to it\n   This works well with [dynamic `import()`](https://developers.google.com/web/updates/2017/11/dynamic-import), so you can lazily load js-ipfs when it is needed.\n   --\u003e\n- `options` should be an object which specifies [advanced configurations](https://github.com/ipfs/js-ipfs#ipfs-constructor) to the node.\n- **TIP:** when used in a browser context, use `ipfs-core` for a smaller browser bundle\n\n### `windowIpfs`\n\n[`window.ipfs`](https://github.com/ipfs-shipyard/ipfs-companion/blob/master/docs/window.ipfs.md) was an experiment created by [ipfs-companion](https://github.com/ipfs/ipfs-companion) browser extension.\nIt supported passing an optional list of permissions to [display a single ACL prompt](https://github.com/ipfs-shipyard/ipfs-companion/blob/master/docs/window.ipfs.md#do-i-need-to-confirm-every-api-call) the first time it is used:\n\n```js\nconst { ipfs, provider } = await getIpfs({\n  providers: [\n    windowIpfs({\n      // example\n      permissions: { commands: ['add','cat','id', 'version'] }\n    })\n  ]\n})\n```\n\n### `webExt`\n\n`webExt` looks for an instance in the [background page of a WebExtension](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension/getBackgroundPage)\n(useful only in browser extensions, not regular pages, disabled by default)\n\n```js\nconst { ipfs, provider } = await getIpfs({\n  providers: [\n    webExt()\n  ]\n})\n```\n\n\u003c!-- TODO: improve this API\n\n#### Creating a provider\n\nIf built-in providers do not solve your use case, create your own!\n\nA provider is just a function that returns an async function that returns\n`{ ipfs, provider }`, but we provide `makeProvider` which enables `connectionTest`:\n\n```js\nconst { getIpfs, makeProvider } = require('ipfs-provider')\n\nconst customProvider = makeProvider(async ({ connectionTest }) =\u003e {\n  try {\n    const ipfs = // create IPFS API instance somehow\n    await connectionTest(ipfs)\n    return { ipfs, provider: 'customProvider' }\n  } catch (_) {\n    return null\n  }\n})\n\nconst { ipfs, provider } = await getIpfs({\n  providers: [\n    customProvider()\n  ]\n})\n```\n\n--\u003e\n\n## Test\n\n```console\n$ npm test\n```\n\n## Lint\n\nPerform [`standard`](https://standardjs.com/) linting on the code:\n\n```console\n$ npm run lint\n```\n\n## Contribute\n\nFeel free to dive in! [Open an issue](https://github.com/ipfs-shipyard/ipfs-provider/issues/new) or submit PRs.\n\nTo contribute to IPFS in general, see the [contributing guide](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md).\n\n[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md)\n\n## License\n\n[MIT](LICENSE) © Protocol Labs\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fipfs-shipyard%2Fipfs-provider","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fipfs-shipyard%2Fipfs-provider","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fipfs-shipyard%2Fipfs-provider/lists"}