diff --git a/packages/helia/src/utils/libp2p.ts b/packages/helia/src/utils/libp2p.ts index e78a1f1f..64a3b56e 100644 --- a/packages/helia/src/utils/libp2p.ts +++ b/packages/helia/src/utils/libp2p.ts @@ -5,7 +5,7 @@ import { createLibp2p as create } from 'libp2p' import { libp2pDefaults } from './libp2p-defaults.js' import type { DefaultLibp2pServices } from './libp2p-defaults.js' import type { ComponentLogger, Libp2p, PeerId } from '@libp2p/interface' -import type { KeychainInit } from '@libp2p/keychain' +import type { Keychain, KeychainInit } from '@libp2p/keychain' import type { Datastore } from 'interface-datastore' import type { Libp2pOptions } from 'libp2p' @@ -23,31 +23,40 @@ export interface Libp2pDefaultsOptions { } export async function createLibp2p = DefaultLibp2pServices> (options: CreateLibp2pOptions): Promise> { - let peerId = options.libp2p?.peerId + const peerId = options.libp2p?.peerId const logger = options.logger ?? defaultLogger() + const selfKey = new Key('/pkcs8/self') + let chain: Keychain | undefined // if no peer id was passed, try to load it from the keychain - if (peerId == null) { - const chain = keychain(options.keychain)({ + if (peerId == null && options.datastore != null) { + chain = keychain(options.keychain)({ datastore: options.datastore, logger }) - const selfKey = new Key('/pkcs8/self') - if (await options.datastore.has(selfKey)) { // load the peer id from the keychain - peerId = await chain.exportPeerId('self') + options.libp2p = options.libp2p ?? {} + options.libp2p.peerId = await chain.exportPeerId('self') } } const defaults = libp2pDefaults(options) + defaults.datastore = defaults.datastore ?? options.datastore options = options ?? {} // @ts-expect-error derived ServiceMap is not compatible with ServiceFactoryMap - return create({ + const node = await create({ ...defaults, ...options.libp2p, start: false }) + + if (peerId == null && chain != null && !await options.datastore.has(selfKey)) { + // persist the peer id in the keychain for next time + await chain.importPeer('self', node.peerId) + } + + return node } diff --git a/packages/helia/test/index.spec.ts b/packages/helia/test/index.spec.ts index 5d3a22cb..470f3062 100644 --- a/packages/helia/test/index.spec.ts +++ b/packages/helia/test/index.spec.ts @@ -1,32 +1,12 @@ /* eslint-env mocha */ -import { noise } from '@chainsafe/libp2p-noise' -import { yamux } from '@chainsafe/libp2p-yamux' -import { webSockets } from '@libp2p/websockets' import { expect } from 'aegir/chai' -import { MemoryBlockstore } from 'blockstore-core' -import { MemoryDatastore } from 'datastore-core' -import { createLibp2p } from 'libp2p' import { createHelia, type HeliaLibp2p } from '../src/index.js' describe('helia', () => { let helia: HeliaLibp2p beforeEach(async () => { - helia = await createHelia({ - datastore: new MemoryDatastore(), - blockstore: new MemoryBlockstore(), - libp2p: await createLibp2p({ - transports: [ - webSockets() - ], - connectionEncryption: [ - noise() - ], - streamMuxers: [ - yamux() - ] - }) - }) + helia = await createHelia() }) afterEach(async () => { @@ -54,4 +34,17 @@ describe('helia', () => { it('should have a libp2p', async () => { expect(helia).to.have.property('libp2p').that.is.ok() }) + + it('should have the same peer id after a restart', async () => { + const datastore = helia.datastore + const peerId = helia.libp2p.peerId + + await helia.stop() + + helia = await createHelia({ + datastore + }) + + expect(helia.libp2p.peerId.toString()).to.equal(peerId.toString()) + }) })