From 45c9d896afa27f5ea043cc5f576d50fc4fa556e9 Mon Sep 17 00:00:00 2001 From: Alex Potsides Date: Fri, 19 May 2023 16:10:09 +0100 Subject: [PATCH] feat: provide default libp2p instance (#127) The original intention was to allow users to configure a libp2p node to their requirements but it's a non-trivial undertaking unless the user is deeply familiar with the libp2p stack. Instead, let's provide node and browser libp2p instances with sensible defaults that give the user the best chance of success on first try. Fixes #121 --- packages/helia/package.json | 31 +++++--- packages/helia/src/helia.ts | 65 ++++++----------- packages/helia/src/index.ts | 33 ++++++--- packages/helia/src/utils/libp2p.browser.ts | 68 ++++++++++++++++++ packages/helia/src/utils/libp2p.ts | 72 +++++++++++++++++++ packages/helia/test/factory.spec.ts | 38 ++++++++++ packages/helia/test/gc.spec.ts | 7 +- packages/helia/test/index.spec.ts | 41 ----------- packages/interface/package.json | 7 +- packages/interface/src/index.ts | 13 +--- packages/interop/package.json | 12 ++-- packages/interop/test/blockstore.spec.ts | 4 +- .../test/fixtures/create-helia.browser.ts | 9 ++- .../interop/test/fixtures/create-helia.ts | 5 +- packages/interop/test/hashes.spec.ts | 4 +- 15 files changed, 277 insertions(+), 132 deletions(-) create mode 100644 packages/helia/src/utils/libp2p.browser.ts create mode 100644 packages/helia/src/utils/libp2p.ts create mode 100644 packages/helia/test/factory.spec.ts diff --git a/packages/helia/package.json b/packages/helia/package.json index f787322c2..1b7b81a25 100644 --- a/packages/helia/package.json +++ b/packages/helia/package.json @@ -138,18 +138,30 @@ "release": "aegir release" }, "dependencies": { + "@chainsafe/libp2p-gossipsub": "^8.0.0", + "@chainsafe/libp2p-noise": "^12.0.0", + "@chainsafe/libp2p-yamux": "^4.0.2", "@helia/interface": "^1.0.0", - "@ipld/dag-pb": "^4.0.2", - "@libp2p/interface-libp2p": "^1.1.0", - "@libp2p/interfaces": "^3.3.1", - "@libp2p/logger": "^2.0.5", + "@ipld/dag-pb": "^4.0.3", + "@libp2p/bootstrap": "^8.0.0", + "@libp2p/interface-libp2p": "^3.1.0", + "@libp2p/interface-pubsub": "^4.0.1", + "@libp2p/interfaces": "^3.3.2", + "@libp2p/ipni-content-routing": "^1.0.0", + "@libp2p/kad-dht": "^9.3.3", + "@libp2p/logger": "^2.0.7", + "@libp2p/mdns": "^8.0.0", + "@libp2p/mplex": "^8.0.3", + "@libp2p/tcp": "^7.0.1", + "@libp2p/webrtc": "^2.0.4", + "@libp2p/webtransport": "^2.0.1", "blockstore-core": "^4.0.0", "cborg": "^1.10.0", "datastore-core": "^9.0.0", "interface-blockstore": "^5.0.0", "interface-datastore": "^8.0.0", "interface-store": "^5.0.1", - "ipfs-bitswap": "^17.0.0", + "ipfs-bitswap": "^18.0.0", "it-all": "^3.0.1", "it-drain": "^3.0.1", "it-filter": "^3.0.1", @@ -162,18 +174,19 @@ "uint8arrays": "^4.0.3" }, "devDependencies": { - "@chainsafe/libp2p-noise": "^11.0.0", - "@chainsafe/libp2p-yamux": "^3.0.5", "@ipld/dag-cbor": "^9.0.0", "@ipld/dag-json": "^10.0.1", - "@libp2p/websockets": "^5.0.3", + "@libp2p/websockets": "^6.0.1", "@types/sinon": "^10.0.14", "aegir": "^39.0.4", "delay": "^5.0.0", - "libp2p": "^0.44.0", + "libp2p": "^0.45.1", "sinon": "^15.0.2", "sinon-ts": "^1.0.0" }, + "browser": { + "./dist/src/utils/libp2p.js": "./dist/src/utils/libp2p.browser.js" + }, "typedoc": { "entryPoint": "./src/index.ts" } diff --git a/packages/helia/src/helia.ts b/packages/helia/src/helia.ts index c6edd79fb..be5413704 100644 --- a/packages/helia/src/helia.ts +++ b/packages/helia/src/helia.ts @@ -1,6 +1,4 @@ import { logger } from '@libp2p/logger' -import { MemoryBlockstore } from 'blockstore-core' -import { MemoryDatastore } from 'datastore-core' import { type Bitswap, createBitswap } from 'ipfs-bitswap' import drain from 'it-drain' import { identity } from 'multiformats/hashes/identity' @@ -13,12 +11,19 @@ import type { HeliaInit } from '.' import type { GCOptions, Helia } from '@helia/interface' import type { Pins } from '@helia/interface/pins' import type { Libp2p } from '@libp2p/interface-libp2p' +import type { Blockstore } from 'interface-blockstore' import type { Datastore } from 'interface-datastore' import type { CID } from 'multiformats/cid' import type { MultihashHasher } from 'multiformats/hashes/interface' const log = logger('helia') +interface HeliaImplInit extends HeliaInit { + libp2p: T + blockstore: Blockstore + datastore: Datastore +} + export class HeliaImpl implements Helia { public libp2p: Libp2p public blockstore: BlockStorage @@ -27,7 +32,7 @@ export class HeliaImpl implements Helia { #bitswap?: Bitswap - constructor (init: HeliaInit) { + constructor (init: HeliaImplInit) { const hashers: MultihashHasher[] = [ sha256, sha512, @@ -35,56 +40,30 @@ export class HeliaImpl implements Helia { ...(init.hashers ?? []) ] - const datastore = init.datastore ?? new MemoryDatastore() - const blockstore = init.blockstore ?? new MemoryBlockstore() + this.#bitswap = createBitswap(init.libp2p, init.blockstore, { + hashLoader: { + getHasher: async (codecOrName: string | number): Promise> => { + const hasher = hashers.find(hasher => { + return hasher.code === codecOrName || hasher.name === codecOrName + }) - // @ts-expect-error incomplete libp2p implementation - const libp2p = init.libp2p ?? new Proxy({}, { - get (_, prop): true | (() => void) { - const noop = (): void => {} - const noops = ['start', 'stop'] - - if (noops.includes(prop.toString())) { - return noop - } + if (hasher != null) { + return hasher + } - if (prop === 'isProxy') { - return true + throw new Error(`Could not load hasher for code/name "${codecOrName}"`) } - - throw new Error('Please configure Helia with a libp2p instance') - }, - set (): never { - throw new Error('Please configure Helia with a libp2p instance') } }) - if (init.libp2p != null) { - this.#bitswap = createBitswap(libp2p, blockstore, { - hashLoader: { - getHasher: async (codecOrName: string | number): Promise> => { - const hasher = hashers.find(hasher => { - return hasher.code === codecOrName || hasher.name === codecOrName - }) - - if (hasher != null) { - return hasher - } - - throw new Error(`Could not load hasher for code/name "${codecOrName}"`) - } - } - }) - } - - this.pins = new PinsImpl(datastore, blockstore, init.dagWalkers ?? []) + this.pins = new PinsImpl(init.datastore, init.blockstore, init.dagWalkers ?? []) - this.libp2p = libp2p - this.blockstore = new BlockStorage(blockstore, this.pins, { + this.libp2p = init.libp2p + this.blockstore = new BlockStorage(init.blockstore, this.pins, { bitswap: this.#bitswap, holdGcLock: init.holdGcLock }) - this.datastore = datastore + this.datastore = init.datastore } async start (): Promise { diff --git a/packages/helia/src/index.ts b/packages/helia/src/index.ts index 1a7e81465..668e303e5 100644 --- a/packages/helia/src/index.ts +++ b/packages/helia/src/index.ts @@ -6,7 +6,6 @@ * @example * * ```typescript - * import { createLibp2p } from 'libp2p' * import { MemoryDatastore } from 'datastore-core' * import { MemoryBlockstore } from 'blockstore-core' * import { createHelia } from 'helia' @@ -15,19 +14,21 @@ * * const node = await createHelia({ * blockstore: new MemoryBlockstore(), - * datastore: new MemoryDatastore(), - * libp2p: await createLibp2p({ - * //... libp2p options - * }) + * datastore: new MemoryDatastore() * }) * const fs = unixfs(node) * fs.cat(CID.parse('bafyFoo')) * ``` */ +import { MemoryBlockstore } from 'blockstore-core' +import { MemoryDatastore } from 'datastore-core' import { HeliaImpl } from './helia.js' +import { createLibp2p } from './utils/libp2p.js' import type { Helia } from '@helia/interface' import type { Libp2p } from '@libp2p/interface-libp2p' +import type { PubSub } from '@libp2p/interface-pubsub' +import type { DualKadDHT } from '@libp2p/kad-dht' import type { Blockstore } from 'interface-blockstore' import type { Datastore } from 'interface-datastore' import type { CID } from 'multiformats/cid' @@ -44,11 +45,11 @@ export interface DAGWalker { /** * Options used to create a Helia node. */ -export interface HeliaInit { +export interface HeliaInit { /** * A libp2p node is required to perform network operations */ - libp2p?: Libp2p + libp2p?: T /** * The blockstore is where blocks are stored @@ -100,8 +101,22 @@ export interface HeliaInit { /** * Create and return a Helia node */ -export async function createHelia (init: HeliaInit = {}): Promise { - const helia = new HeliaImpl(init) +export async function createHelia (init: HeliaInit): Promise> +export async function createHelia (init?: HeliaInit>): Promise>> +export async function createHelia (init: HeliaInit = {}): Promise> { + const datastore = init.datastore ?? new MemoryDatastore() + const blockstore = init.blockstore ?? new MemoryBlockstore() + const libp2p = init.libp2p ?? await createLibp2p({ + datastore, + start: false + }) + + const helia = new HeliaImpl({ + ...init, + datastore, + blockstore, + libp2p + }) if (init.start !== false) { await helia.start() diff --git a/packages/helia/src/utils/libp2p.browser.ts b/packages/helia/src/utils/libp2p.browser.ts new file mode 100644 index 000000000..17a443323 --- /dev/null +++ b/packages/helia/src/utils/libp2p.browser.ts @@ -0,0 +1,68 @@ +import { gossipsub } from '@chainsafe/libp2p-gossipsub' +import { noise } from '@chainsafe/libp2p-noise' +import { yamux } from '@chainsafe/libp2p-yamux' +import { bootstrap } from '@libp2p/bootstrap' +import { ipniContentRouting } from '@libp2p/ipni-content-routing' +import { kadDHT, type DualKadDHT } from '@libp2p/kad-dht' +import { mplex } from '@libp2p/mplex' +import { webRTC, webRTCDirect } from '@libp2p/webrtc' +import { webSockets } from '@libp2p/websockets' +import { webTransport } from '@libp2p/webtransport' +import { createLibp2p as create } from 'libp2p' +import { autoNATService } from 'libp2p/autonat' +import { circuitRelayTransport, circuitRelayServer } from 'libp2p/circuit-relay' +import { identifyService } from 'libp2p/identify' +import type { CreateLibp2pOptions } from './libp2p.js' +import type { Libp2p } from '@libp2p/interface-libp2p' +import type { PubSub } from '@libp2p/interface-pubsub' + +export async function createLibp2p (opts: CreateLibp2pOptions): Promise> { + return create({ + ...opts, + addresses: { + listen: [ + '/webrtc' + ] + }, + transports: [ + webRTC(), + webRTCDirect(), + webTransport(), + webSockets(), + circuitRelayTransport({ + discoverRelays: 1 + }) + ], + connectionEncryption: [ + noise() + ], + streamMuxers: [ + yamux(), + mplex() + ], + peerDiscovery: [ + bootstrap({ + list: [ + '/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN', + '/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa', + '/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb', + '/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt' + ] + }) + ], + contentRouters: [ + ipniContentRouting('https://cid.contact') + ], + services: { + identify: identifyService(), + autoNAT: autoNATService(), + pubsub: gossipsub(), + dht: kadDHT({ + clientMode: true + }), + relay: circuitRelayServer({ + advertise: true + }) + } + }) +} diff --git a/packages/helia/src/utils/libp2p.ts b/packages/helia/src/utils/libp2p.ts new file mode 100644 index 000000000..c73e436bb --- /dev/null +++ b/packages/helia/src/utils/libp2p.ts @@ -0,0 +1,72 @@ +import { gossipsub } from '@chainsafe/libp2p-gossipsub' +import { noise } from '@chainsafe/libp2p-noise' +import { yamux } from '@chainsafe/libp2p-yamux' +import { bootstrap } from '@libp2p/bootstrap' +import { ipniContentRouting } from '@libp2p/ipni-content-routing' +import { type DualKadDHT, kadDHT } from '@libp2p/kad-dht' +import { mdns } from '@libp2p/mdns' +import { mplex } from '@libp2p/mplex' +import { tcp } from '@libp2p/tcp' +import { webSockets } from '@libp2p/websockets' +import { createLibp2p as create } from 'libp2p' +import { autoNATService } from 'libp2p/autonat' +import { circuitRelayTransport, circuitRelayServer, type CircuitRelayService } from 'libp2p/circuit-relay' +import { identifyService } from 'libp2p/identify' +import { uPnPNATService } from 'libp2p/upnp-nat' +import type { Libp2p } from '@libp2p/interface-libp2p' +import type { PubSub } from '@libp2p/interface-pubsub' +import type { Datastore } from 'interface-datastore' + +export interface CreateLibp2pOptions { + datastore: Datastore + start?: boolean +} + +export async function createLibp2p (opts: CreateLibp2pOptions): Promise> { + return create({ + ...opts, + addresses: { + listen: [ + '/ip4/0.0.0.0/tcp/0' + ] + }, + transports: [ + tcp(), + webSockets(), + circuitRelayTransport({ + discoverRelays: 1 + }) + ], + connectionEncryption: [ + noise() + ], + streamMuxers: [ + yamux(), + mplex() + ], + peerDiscovery: [ + mdns(), + bootstrap({ + list: [ + '/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN', + '/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa', + '/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb', + '/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt' + ] + }) + ], + contentRouters: [ + ipniContentRouting('https://cid.contact') + ], + services: { + identify: identifyService(), + autoNAT: autoNATService(), + upnp: uPnPNATService(), + pubsub: gossipsub(), + dht: kadDHT(), + relay: circuitRelayServer({ + advertise: true + }) + } + }) +} diff --git a/packages/helia/test/factory.spec.ts b/packages/helia/test/factory.spec.ts new file mode 100644 index 000000000..b15057414 --- /dev/null +++ b/packages/helia/test/factory.spec.ts @@ -0,0 +1,38 @@ +/* eslint-env mocha */ + +import { expect } from 'aegir/chai' +import { Key } from 'interface-datastore' +import { CID } from 'multiformats/cid' +import { createHelia } from '../src/index.js' +import type { Helia } from '@helia/interface' + +describe('helia factory', () => { + let helia: Helia + + afterEach(async () => { + if (helia != null) { + await helia.stop() + } + }) + + it('allows creating offline node', async () => { + helia = await createHelia({ + start: false + }) + + expect(helia.libp2p.isStarted()).to.be.false() + }) + + it('does not require any constructor args', async () => { + helia = await createHelia() + + const cid = CID.parse('QmaQwYWpchozXhFv8nvxprECWBSCEppN9dfd2VQiJfRo3F') + const block = Uint8Array.from([0, 1, 2, 3]) + await helia.blockstore.put(cid, block) + expect(await helia.blockstore.has(cid)).to.be.true() + + const key = new Key(`/${cid.toString()}`) + await helia.datastore.put(key, block) + expect(await helia.datastore.has(key)).to.be.true() + }) +}) diff --git a/packages/helia/test/gc.spec.ts b/packages/helia/test/gc.spec.ts index 506159e6b..ce0e37029 100644 --- a/packages/helia/test/gc.spec.ts +++ b/packages/helia/test/gc.spec.ts @@ -1,4 +1,5 @@ /* eslint-env mocha */ + import { noise } from '@chainsafe/libp2p-noise' import { yamux } from '@chainsafe/libp2p-yamux' import * as dagCbor from '@ipld/dag-cbor' @@ -41,7 +42,7 @@ describe('gc', () => { } }) - it('pins a dag-pb node and does not garbage collect it or it\'s children', async () => { + it('pins a dag-pb node and does not garbage collect it or its children', async () => { const child1 = await createAndPutBlock(dagPb.code, dagPb.encode({ Data: Uint8Array.from([0, 1, 2, 3]), Links: [] @@ -82,7 +83,7 @@ describe('gc', () => { await expect(helia.blockstore.has(doomed)).to.eventually.be.false() }) - it('pins a dag-cbor node and does not garbage collect it or it\'s children', async () => { + it('pins a dag-cbor node and does not garbage collect it or its children', async () => { const child1 = await createAndPutBlock(dagCbor.code, dagCbor.encode({ foo: 'bar' }), helia.blockstore) @@ -117,7 +118,7 @@ describe('gc', () => { await expect(helia.blockstore.has(doomed)).to.eventually.be.false() }) - it('pins a dag-json node and does not garbage collect it or it\'s children', async () => { + it('pins a dag-json node and does not garbage collect it or its children', async () => { const child1 = await createAndPutBlock(dagJson.code, dagJson.encode({ foo: 'bar' }), helia.blockstore) diff --git a/packages/helia/test/index.spec.ts b/packages/helia/test/index.spec.ts index 1c1dd732a..d70d041b9 100644 --- a/packages/helia/test/index.spec.ts +++ b/packages/helia/test/index.spec.ts @@ -5,9 +5,7 @@ import { webSockets } from '@libp2p/websockets' import { expect } from 'aegir/chai' import { MemoryBlockstore } from 'blockstore-core' import { MemoryDatastore } from 'datastore-core' -import { Key } from 'interface-datastore' import { createLibp2p } from 'libp2p' -import { CID } from 'multiformats/cid' import { createHelia } from '../src/index.js' import type { Helia } from '@helia/interface' @@ -57,43 +55,4 @@ describe('helia', () => { it('should have a libp2p', async () => { expect(helia).to.have.property('libp2p').that.is.ok() }) - - it('allows creating offline node', async () => { - const helia = await createHelia({ - start: false, - datastore: new MemoryDatastore(), - blockstore: new MemoryBlockstore(), - libp2p: await createLibp2p({ - start: false, - transports: [ - webSockets() - ], - connectionEncryption: [ - noise() - ], - streamMuxers: [ - yamux() - ] - }) - }) - - expect(helia.libp2p.isStarted()).to.be.false() - }) - - it('does not require any constructor args', async () => { - const helia = await createHelia() - - const cid = CID.parse('QmaQwYWpchozXhFv8nvxprECWBSCEppN9dfd2VQiJfRo3F') - const block = Uint8Array.from([0, 1, 2, 3]) - await helia.blockstore.put(cid, block) - expect(await helia.blockstore.has(cid)).to.be.true() - - const key = new Key(`/${cid.toString()}`) - await helia.datastore.put(key, block) - expect(await helia.datastore.has(key)).to.be.true() - - expect(() => { - helia.libp2p.isStarted() - }).to.throw('Please configure Helia with a libp2p instance') - }) }) diff --git a/packages/interface/package.json b/packages/interface/package.json index ece335caa..fa7a901e7 100644 --- a/packages/interface/package.json +++ b/packages/interface/package.json @@ -155,13 +155,12 @@ "release": "aegir release" }, "dependencies": { - "@libp2p/interface-libp2p": "^1.1.0", - "@libp2p/interface-peer-id": "^2.0.1", - "@libp2p/interfaces": "^3.3.1", + "@libp2p/interface-libp2p": "^3.1.0", + "@libp2p/interfaces": "^3.3.2", "interface-blockstore": "^5.0.0", "interface-datastore": "^8.0.0", "interface-store": "^5.0.1", - "ipfs-bitswap": "^17.0.0", + "ipfs-bitswap": "^18.0.0", "multiformats": "^11.0.1", "progress-events": "^1.0.0" }, diff --git a/packages/interface/src/index.ts b/packages/interface/src/index.ts index b73309647..83fafa151 100644 --- a/packages/interface/src/index.ts +++ b/packages/interface/src/index.ts @@ -17,7 +17,6 @@ import type { Blocks } from './blocks.js' import type { Pins } from './pins.js' import type { Libp2p } from '@libp2p/interface-libp2p' -import type { PeerId } from '@libp2p/interface-peer-id' import type { AbortOptions } from '@libp2p/interfaces' import type { Datastore } from 'interface-datastore' import type { CID } from 'multiformats/cid' @@ -28,11 +27,11 @@ export type { Await, AwaitIterable } from 'interface-store' /** * The API presented by a Helia node. */ -export interface Helia { +export interface Helia { /** * The underlying libp2p node */ - libp2p: Libp2p + libp2p: T /** * Where the blocks are stored @@ -72,11 +71,3 @@ export type GcEvents = export interface GCOptions extends AbortOptions, ProgressOptions { } - -export interface InfoOptions extends AbortOptions { - /** - * If passed, return information about this PeerId, defaults - * to the ID of the current node. - */ - peerId?: PeerId -} diff --git a/packages/interop/package.json b/packages/interop/package.json index 528ca330b..cc0fe21dd 100644 --- a/packages/interop/package.json +++ b/packages/interop/package.json @@ -52,21 +52,21 @@ "test:electron-main": "aegir test -t electron-main" }, "devDependencies": { - "@chainsafe/libp2p-noise": "^11.0.0", - "@chainsafe/libp2p-yamux": "^3.0.5", + "@chainsafe/libp2p-noise": "^12.0.0", + "@chainsafe/libp2p-yamux": "^4.0.2", "@helia/interface": "^1.0.0", - "@libp2p/tcp": "^6.1.2", - "@libp2p/websockets": "^5.0.3", + "@libp2p/tcp": "^7.0.1", + "@libp2p/websockets": "^6.0.1", "@multiformats/sha3": "^2.0.15", "aegir": "^39.0.4", "blockstore-core": "^4.0.0", "datastore-core": "^9.0.0", - "go-ipfs": "^0.19.0", + "go-ipfs": "^0.20.0", "helia": "^1.0.0", "ipfsd-ctl": "^13.0.0", "it-to-buffer": "^4.0.1", "kubo-rpc-client": "^3.0.0", - "libp2p": "^0.44.0", + "libp2p": "^0.45.1", "multiformats": "^11.0.1" }, "browser": { diff --git a/packages/interop/test/blockstore.spec.ts b/packages/interop/test/blockstore.spec.ts index bf2061650..f91a526bb 100644 --- a/packages/interop/test/blockstore.spec.ts +++ b/packages/interop/test/blockstore.spec.ts @@ -19,7 +19,9 @@ describe('blockstore', () => { kubo = await createKuboNode() // connect the two nodes - await helia.libp2p.peerStore.addressBook.add(kubo.peer.id, kubo.peer.addresses) + await helia.libp2p.peerStore.merge(kubo.peer.id, { + multiaddrs: kubo.peer.addresses + }) await helia.libp2p.dial(kubo.peer.id) }) diff --git a/packages/interop/test/fixtures/create-helia.browser.ts b/packages/interop/test/fixtures/create-helia.browser.ts index 1678d8621..38864c445 100644 --- a/packages/interop/test/fixtures/create-helia.browser.ts +++ b/packages/interop/test/fixtures/create-helia.browser.ts @@ -6,6 +6,7 @@ import { MemoryBlockstore } from 'blockstore-core' import { MemoryDatastore } from 'datastore-core' import { createHelia, type HeliaInit } from 'helia' import { createLibp2p } from 'libp2p' +import { identifyService } from 'libp2p/identify' import type { Helia } from '@helia/interface' export async function createHeliaNode (init?: Partial): Promise { @@ -26,8 +27,12 @@ export async function createHeliaNode (init?: Partial): Promise false } }) diff --git a/packages/interop/test/fixtures/create-helia.ts b/packages/interop/test/fixtures/create-helia.ts index 16c940de8..ed30023a3 100644 --- a/packages/interop/test/fixtures/create-helia.ts +++ b/packages/interop/test/fixtures/create-helia.ts @@ -5,6 +5,7 @@ import { MemoryBlockstore } from 'blockstore-core' import { MemoryDatastore } from 'datastore-core' import { createHelia, type HeliaInit } from 'helia' import { createLibp2p } from 'libp2p' +import { identifyService } from 'libp2p/identify' import type { Helia } from '@helia/interface' export async function createHeliaNode (init?: Partial): Promise { @@ -27,8 +28,8 @@ export async function createHeliaNode (init?: Partial): Promise { kubo = await createKuboNode() // connect the two nodes - await helia.libp2p.peerStore.addressBook.add(kubo.peer.id, kubo.peer.addresses) + await helia.libp2p.peerStore.merge(kubo.peer.id, { + multiaddrs: kubo.peer.addresses + }) await helia.libp2p.dial(kubo.peer.id) })