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 f787322c..1b7b81a2 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 c6edd79f..be541370 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 1a7e8146..668e303e 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 00000000..17a44332 --- /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 00000000..c73e436b --- /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 00000000..b1505741 --- /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 506159e6..ce0e3702 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 1c1dd732..d70d041b 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 ece335ca..fa7a901e 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 b7330964..83fafa15 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 528ca330..cc0fe21d 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 bf206165..f91a526b 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 1678d862..38864c44 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 16c940de..ed30023a 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) })