Returns IPFS API object by trying multiple providers in a custom fallback order.
This is a general-purpose replacement for ipfs-redux-bundle.
$ npm install ipfs-provider
<!-- 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.
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
andwebExt
.
- built-in names match constants from
apiAddress
– returned only whenhttpClient
provider is used, provides information which HTTP endpoint succeded
See examples/
for sample code and demonstration of advanced fallback strategies.
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()
]
})
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 */ },
})
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):
apiAddress
(if provided)/api/
at the current Origin- 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):
- one returned by
loadHttpClientModule
async function (if provided) - 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.
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 constructoroptions
should be an object which specifies advanced configurations to the node.
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
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()
]
})
$ npm test
Perform standard
linting on the code:
$ npm run lint
Feel free to dive in! Open an issue or submit PRs.
To contribute to IPFS in general, see the contributing guide.
MIT © Protocol Labs