Skip to content

xmaysonnave/ipfs-provider

 
 

Repository files navigation

ipfs-provider

Build Status Dependency Status

Returns IPFS API object by trying multiple providers in a custom fallback order.

This is a general-purpose replacement for ipfs-redux-bundle.

Install

via NPM

$ npm install ipfs-provider

via prebuilt browser bundles

<!-- remember to include js-ipfs and js-ipfs-http-client, if they are used -->
<script src="https://cdn.jsdelivr.net/npm/ipfs/dist/index.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/ipfs-http-client/dist/index.min.js"></script>

<!-- prebuilt and minified bundle -->
<script src="https://cdn.jsdelivr.net/npm/ipfs-provider/dist/index.min.js"></script>

<script>
  const { getIpfs, providers } = window.IpfsProvider
  const { ipfs, provider, apiAddress } = await getIpfs({
    loadHttpClientModule: () => window.IpfsHttpClient,
    loadJsIpfsModule: () => window.Ipfs,
    providers: [ /* see Usage below */ ]
    })
</script>

Note: when using prebuilt bundles in production use explicit versions and SRI hashes. Details here.

Usage

const { getIpfs, providers } = require('ipfs-provider')
const { httpClient, jsIpfs, windowIpfs } = providers

const { ipfs, provider, apiAddress } = await getIpfs({
  // when httpClient provider is used multiple times
  // define its constructor once, at the top level
  loadHttpClientModule: () => require('ipfs-http-client'),

  // note this is an array, providers are tried in order:
  providers: [

    // (1) try window.ipfs (experimental, but some browsers expose it),
    windowIpfs({
      // request specific permissions upfront (optional)
      permissions: { commands: ['files.add', 'files.cat'] }
    }),

    // (2) try various HTTP endpoints (best-effort),
    httpClient({
      // (2.1) try multiaddr of a local node
      apiAddress: '/ip4/127.0.0.1/tcp/5001'
    }),
    httpClient(), // (2.2) try "/api/v0/" on the same Origin as the page
    httpClient({
      // (2.3) try arbitrary API URL
      apiAddress: 'https://some.example.com:8080'
    }),

    // (3) final fallback to spawning embedded js-ipfs running in-page
    jsIpfs({
      // js-ipfs package is used only once, as a last resort
      loadJsIpfsModule: () => require('ipfs'),
      options: { } // pass config: https://github.com/ipfs/js-ipfs/blob/master/packages/ipfs/docs/MODULE.md#ipfscreateoptions
    })
  ]
})

for await (const file of ipfs.add("text")) {
  if (file && file.cid) {
    console.log(`successfully stored at ${file.cid}`)
  } else {
    console.error('unable to ipfs.add', file)
  }
}
  • ipfs – returned instance of IPFS API (see SPEC)
  • provider – a string with a name of the first successful provider.
    • built-in names match constants from providers: httpClient, jsIpfs, windowIpfs and webExt.
  • apiAddress – returned only when httpClient provider is used, provides information which HTTP endpoint succeded

Examples

See examples/ for sample code and demonstration of advanced fallback strategies.

Providers

You can customize the order of the providers by passing a different array order to the providers array.

For example, if you want to try httpClient and then windowIpfs, you should run it like this:

const { getIpfs, providers } = require('ipfs-provider')
const { httpClient, windowIpfs } = providers

const { ipfs, provider } = await getIpfs({
  providers: [
    httpClient(),
    windowIpfs()
  ]
})

Customizing connection test

const { ipfs, provider } = await getIpfs({
  providers: [ /* array of providers to try in order */ ],
  connectionTest: () => { /* boolean function to test the connection to IPFS, default one tries to ipfs.get the CID of an empty directory */ },
})

httpClient

Tries to connect to HTTP API via js-ipfs-http-client:

const { ipfs, provider } = await getIpfs({
  providers: [
    httpClient({
      loadHttpClientModule: () => require('ipfs-http-client'),
      apiAddress: 'https://api.example.com:8080/'
    })
  ]
})

This provider will attempt to establish connection with (in order):

  1. apiAddress (if provided)
  2. /api/ at the current Origin
  3. the default local API (/ip4/127.0.0.1/tcp/5001)

It supports lazy-loading and small bundle sizes. The client library is initialized using constructor (in order):

  1. one returned by loadHttpClientModule async function (if provided)
  2. one exposed at window.IpfsHttpClient (if present)

Value passed in apiAddress can be:

  • a multiaddr (string like /ip4/127.0.0.1/tcp/5001 or an object)
  • a String with an URL (https://api.example.com:8080/)
  • a configuration object supported by the constructor ({ host: '1.1.1.1', port: '80', apiPath: '/ipfs/api/v0' })

To try multiple endpoints, simply use this provider multiple times. See examples/browser-browserify/src/index.js for real world example.

jsIpfs

Spawns embedded js-ipfs (a full IPFS node in JavaScript) in the context of the current page using customizable constructor:

const { ipfs, provider } = await getIpfs({
  providers: [
    jsIpfs({
      loadJsIpfsModule: () => require('ipfs'),
      options: { /* advanced config */ }
    })
  ]
})
  • loadJsIpfsModule should be a function that returns a promise that resolves to a js-ipfs constructor
  • options should be an object which specifies advanced configurations to the node.

windowIpfs

window.ipfs is created by ipfs-companion browser extension. It supports passing an optional list of permissions to display a single ACL prompt the first time it is used:

const { ipfs, provider } = await getIpfs({
  providers: [
    windowIpfs({
      // example
      permissions: { commands: ['add','cat','id', 'version'] }
    })
  ]
})

webExt

webExt looks for an instance in the background page of a WebExtension (useful only in browser extensions, not regular pages, disabled by default)

const { ipfs, provider } = await getIpfs({
  providers: [
    webExt()
  ]
})

Test

$ npm test

Lint

Perform standard linting on the code:

$ npm run lint

Contribute

Feel free to dive in! Open an issue or submit PRs.

To contribute to IPFS in general, see the contributing guide.

License

MIT © Protocol Labs

About

Connect to IPFS via an available provider

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%