Erebos v0.6 released
Erebos v0.6 is the new version of our JavaScript client for Swarm.
If you are not familiar with Erebos or Swarm yet, you might want to read the introduction blog post first!
This version introduces many changes to the APIs interacting with Swarm feeds. If you have not used feeds before, our previous post provides a short introduction.
Breaking changes
Signature keys
v0.6 introduces lots of changes that caused a larger refactoring of the library. Make sure to read and understand these changes before upgrading.
The main cause of these breaking changes is that the Bzz APIs no longer supports providing and creating signature keys. Instead, a signFeedDigest()
function must be provided by the application in the Bzz
constructor if it needs to publish updates.
As a consequence, the postFeedValue()
method now has a different signature requiring to provide the feed metadata rather than a signature key, and the Bzz
API constructor most now be an object with an url
property and optionally a signFeedDigest()
function.
// Erebos v0.5
const swarm = new SwarmClient({ bzz: 'http://localhost:8500' })// Erebos v0.6
const swarm = new SwarmClient({
bzz: {
url: 'http://localhost:8500',
// Only needed if you need to publish feed updates
signFeedDigest: mySigningFunction,
}
})
The reasons for this change are explained in this GitHub issue.
HTTP headers
Additional request headers should now be provided as part of the options object in various methods rather than as a separate argument.
const headers = { foo: 'bar' }// Erebos v0.5
bzz.upload('hello', { contentType: 'text/plain' }, headers)// Erebos v0.6
bzz.upload('hello', { contentType: 'text/plain', headers })
New packages
keccak256
The added @erebos/keccak256
package provides functions to hash contents and convert an elliptic public key to an Ethereum address, as used by Swarm.
secp256k1
The @erebos/secp256k1
package exposes some of the functions that were previously provided by the Bzz API package in order to create signature keys and sign data.
New features
Request timeout
Fetching data from Swarm may take more time than expected for a good user experience. In Erebos v0.6, requests can now be provided a timeout
option that will throw an error if the request takes too long.
The timeout
option can be provided per request, or at the Bzz
instance level so it applies to all requests. When set to 0
, no timeout is applied, so even if a default timeout is configured at the instance level, it can be prevented for an individual request.
More feed APIs and options
This release aims to support more use-cases for feeds, notably when used to store a hash pointing to another resource. Here are some of the changes:
postSignedFeedValue()
is the lowest-level public method provided to set a feed value, it requires all the feed update data and parameters to be provided. It can be useful when the application handles signing itself.postFeedValue()
needs to be provided the feed update metadata and uses the instance’ssignFeedDigest()
function in order to sign the data. It is the simplest way to to set the feed value when the metadata is known.updateFeedValue()
takes care of fetching the necessary feed metadata, it is a simpler option thanpostFeedValue()
but requires an extra request.uploadFeedValue()
covers the use case of uploading data using theupload()
method and then update a feed value to the hash of the uploaded data.
The getFeedValue()
method has also been updated to support a mode
option, that can be either feed-response
(the default, behaving as in Erebos v0.5), content-hash
or content-response
.
Both content-hash
and content-response
assume the feed value is a Swarm hash pointing to another resource. When its mode
is set to content-hash
, getFeedValue()
will parse and return the value as an hexadecimal string, and when set to content-response
, it will call the download()
method and return its HTTP response.
The following pseudo-code illustrates using uploadFeedValue()
and getFeedValue()
:
await bzz.uploadFeedValue(address, 'hello', { name: 'test' })
const res = await bzz.getFeedValue(address, { name: 'test' }, {
mode: 'content-response',
})
const text = await res.text() // 'hello'
By using a feed manifest, the code can be changed to the following:
const hash = await bzz.createFeedManifest(address, { name: 'test' })
await bzz.uploadFeedValue(hash, 'hello')
const res = await bzz.download(hash)
const value = await res.text()
Feed polling support
Beyond fetching a feed value once, other use cases involve polling a feed in order to check if its value has changed, or if a value has been created.
The added pollFeedValue()
method returns a RxJS Observable pushing values based on the various options provided to support these use cases, such as:
interval
: the number of milliseconds between each execution of the flowmode
: described above, implementing the same behaviour as withgetFeedValue()
.whenEmpty
: the behaviour to apply when the feed does not have a value (HTTP status code 404), eitheraccept
(by default), will pushnull
values to the subscriber,ignore
will not push any empty value, anderror
will trigger an error.contentChangedOnly
: can be set totrue
in order to only push values to the subscriber when different from the previous one. This option is only relevant if themode
option is set tocontent-hash
orcontent-response
.
More on feeds
Adding feed polling in Erebos v0.6 is a stepping stone towards supporting more advanced use cases, such as being able to use feeds as a data stream.
This is the purpose of the Feedlinks protocol, a proposed data structure and reference implementation allowing to use feeds as a linked-list. Please join the discussion if you are interested!
Check out the Swarm documentation to get started with Swarm and the updated Erebos documentation to interact with Swarm using the provides APIs and CLI!
Thanks to Attila Gazso for the original idea of injecting an application-provided signature function to support Swarm feed updates and the subsequent feedback!