Converts this module to typescript. - Ecosystem modules renamed from (e.g.) `libp2p-tcp` to `@libp2p/tcp` - Ecosystem module now have named exports - Configuration has been updated, now pass instances of modules instead of classes: - Some configuration keys have been renamed to make them more descriptive. `transport` -> `transports`, `connEncryption` -> `connectionEncryption`. In general where we pass multiple things, the key is now plural, e.g. `streamMuxer` -> `streamMuxers`, `contentRouting` -> `contentRouters`, etc. Where we are configuring a singleton the config key is singular, e.g. `connProtector` -> `connectionProtector` etc. - Properties of the `modules` config key have been moved to the root - Properties of the `config` config key have been moved to the root ```js // before import Libp2p from 'libp2p' import TCP from 'libp2p-tcp' await Libp2p.create({ modules: { transport: [ TCP ], } config: { transport: { [TCP.tag]: { foo: 'bar' } }, relay: { enabled: true, hop: { enabled: true, active: true } } } }) ``` ```js // after import { createLibp2p } from 'libp2p' import { TCP } from '@libp2p/tcp' await createLibp2p({ transports: [ new TCP({ foo: 'bar' }) ], relay: { enabled: true, hop: { enabled: true, active: true } } }) ``` - Use of `enabled` flag has been reduced - previously you could pass a module but disable it with config. Now if you don't want a feature, just don't pass an implementation. Eg: ```js // before await Libp2p.create({ modules: { transport: [ TCP ], pubsub: Gossipsub }, config: { pubsub: { enabled: false } } }) ``` ```js // after await createLibp2p({ transports: [ new TCP() ] }) ``` - `.multiaddrs` renamed to `.getMultiaddrs()` because it's not a property accessor, work is done by that method to calculate announce addresses, observed addresses, etc - `/p2p/${peerId}` is now appended to all addresses returned by `.getMultiaddrs()` so they can be used opaquely (every consumer has to append the peer ID to the address to actually use it otherwise). If you need low-level unadulterated addresses, call methods on the address manager. BREAKING CHANGE: types are no longer hand crafted, this module is now ESM only
5.2 KiB
Migrating to the libp2p@0.27 API
A migration guide for refactoring your application code from libp2p v0.26.x to v0.27.0.
Table of Contents
Migrating from callbacks
Callbacks are no longer supported in the libp2p API, as the API has now fully moved to async / await. You can see a full list of the available methods in the API readme
Before
libp2p.start((err) => {
if (err) throw err
console.log('libp2p started')
})
After
await libp2p.start()
console.log('libp2p started')
Pull Streams to Streaming Iterables
The libp2p API no longer supports Pull Streams and has migrated to Streaming Iterables. If you would like to continue using Pull Streams in your application code, or need additional time to migrate your code base, you can leverage the conversion modules async-iterator-to-pull-stream and pull-stream-to-async-iterator.
For a growing list of async iterator modules, you should follow the it-awesome repo.
Sample API Migrations
Registering Protocol Handlers
Protocol registration is very similar to how it previously was, however, the handler now takes a single parameter containing the incoming stream and its protocol. Additionally, you can now pass an array of protocols to .handle
, but a single string is still supported.
Before
const pull from 'pull-stream')
libp2p.handle('/echo/1.0.0', (protocol, conn) => pull(conn, conn))
After
const pipe from 'it-pipe')
libp2p.handle(['/echo/1.0.0'], ({ protocol, stream }) => pipe(stream, stream))
Dialing and Sending Data
dialProtocol
no longer takes a callback, and will now return a Streaming Iterable and the protocol that was successfully negotiated. The new stream can be used with async iterator modules, see it-awesome, instead of pull streams.
Before
const pull from 'pull-stream')
libp2p.dialProtocol(peerInfo, '/echo/1.0.0', (err, conn) => {
if (err) { throw err }
pull(
pull.values(['hey']),
conn,
pull.drain((data) => {
console.log('received echo:', data.toString())
}, (err) => {
if (err) { throw err }
})
)
})
After
const pipe from 'it-pipe')
const { protocol, stream } = await libp2p.dialProtocol(peerInfo, '/echo/1.0.0')
await pipe(
['hey'],
stream,
async function (source) {
for await (const data of source) {
console.log('received echo:', data.toString())
}
}
)
Checking if a peer is connected
peerInfo.isConnected
has been deprecated. libp2p now tracks all connections centrally and will no longer update the state of peerInfo.isConnected
. Consumers should switch to using libp2p.registrar.getConnection(peerInfo)
, which will return an open connection to that peer if one exists.
Before
if (peerInfo.isConnected()) {
// ...do something if connected
}
After
const connection = libp2p.registrar.getConnection(peerInfo)
if (connection) {
// ...do something if connected
}
Pinging another peer
libp2p.ping
will no longer callback with a Ping
event emitter. The internal logic has been simplified to give more flexibility to the API. libp2p.ping
will now execute a single ping and return the latency.
Before
libp2p.ping(peerInfo, (err, ping) => {
if (err) throw err
ping.once('ping', (latency) => {
console.log('Latency is %s ms', latency)
ping.stop()
})
ping.start()
})
After
const latency = await libp2p.ping(peerInfo)
console.log('Latency is %s ms', latency)
Pubsub
Getting subscribers
libp2p.pubsub.peers()
is now libp2p.pubsub.getSubscribers()
and is no longer an asynchronous action.
Before
libp2p.pubsub.peers(topic, (err, subscribers) => {
if (err) throw err
console.log('Subscribers:', subscribers)
})
After
const subscribers = libp2p.pubsub.getSubscribers(topic)
console.log('Subscribers:', subscribers)
Getting subscribed topics
libp2p.pubsub.ls()
is now libp2p.pubsub.getTopics()
and is no longer an asynchronous action.
Before
libp2p.pubsub.ls((err, topics) => {
if (err) throw err
console.log('Topics:', topics)
})
After
const topics = libp2p.pubsub.getTopics()
console.log('Topics:', topics)