diff --git a/packages/verified-fetch/package.json b/packages/verified-fetch/package.json index 2fec572d..559e7b38 100644 --- a/packages/verified-fetch/package.json +++ b/packages/verified-fetch/package.json @@ -57,52 +57,52 @@ "release": "aegir release" }, "dependencies": { - "@helia/block-brokers": "^3.0.1", - "@helia/car": "^3.1.5", - "@helia/http": "^1.0.8", - "@helia/interface": "^4.3.0", - "@helia/ipns": "^7.2.2", - "@helia/routers": "^1.1.0", - "@ipld/dag-cbor": "^9.2.0", - "@ipld/dag-json": "^10.2.0", - "@ipld/dag-pb": "^4.1.0", - "@libp2p/interface": "^1.4.0", - "@libp2p/kad-dht": "^12.0.17", - "@libp2p/peer-id": "^4.1.2", + "@helia/block-brokers": "^4.0.0", + "@helia/car": "^4.0.0", + "@helia/http": "^2.0.0", + "@helia/interface": "^5.0.0", + "@helia/ipns": "^8.0.0", + "@helia/routers": "^2.0.0", + "@helia/unixfs": "^4.0.0", + "@ipld/dag-cbor": "^9.2.1", + "@ipld/dag-json": "^10.2.2", + "@ipld/dag-pb": "^4.1.2", + "@libp2p/interface": "^2.1.3", + "@libp2p/kad-dht": "^14.0.1", + "@libp2p/peer-id": "^5.0.5", "@multiformats/dns": "^1.0.6", - "cborg": "^4.2.0", + "cborg": "^4.2.4", "hashlru": "^2.3.0", - "interface-blockstore": "^5.2.10", - "interface-datastore": "^8.2.11", - "ipfs-unixfs-exporter": "^13.5.0", - "it-map": "^3.1.0", + "interface-blockstore": "^5.3.1", + "interface-datastore": "^8.3.1", + "ipfs-unixfs-exporter": "^13.6.1", + "it-map": "^3.1.1", "it-pipe": "^3.0.1", "it-tar": "^6.0.5", "it-to-browser-readablestream": "^2.0.9", "lru-cache": "^10.2.2", - "multiformats": "^13.1.0", - "progress-events": "^1.0.0", + "multiformats": "^13.3.0", + "progress-events": "^1.0.1", "uint8arrays": "^5.1.0" }, "devDependencies": { - "@helia/dag-cbor": "^3.0.4", - "@helia/dag-json": "^3.0.4", - "@helia/json": "^3.0.4", - "@helia/unixfs": "^3.0.6", - "@helia/utils": "^0.3.1", - "@ipld/car": "^5.3.0", - "@libp2p/interface-compliance-tests": "^5.4.5", - "@libp2p/logger": "^4.0.13", - "@libp2p/peer-id-factory": "^4.1.2", + "@helia/dag-cbor": "^4.0.0", + "@helia/dag-json": "^4.0.0", + "@helia/json": "^4.0.0", + "@helia/utils": "^1.0.0", + "@ipld/car": "^5.3.2", + "@libp2p/crypto": "^5.0.5", + "@libp2p/interface-compliance-tests": "^6.1.6", + "@libp2p/logger": "^5.1.1", "@sgtpooki/file-type": "^1.0.1", "@types/sinon": "^17.0.3", "aegir": "^42.2.11", - "blockstore-core": "^4.4.1", + "blockstore-core": "^5.0.2", "browser-readablestream-to-it": "^2.0.7", - "datastore-core": "^9.2.9", - "helia": "^4.2.2", - "ipfs-unixfs-importer": "^15.2.5", - "ipns": "^9.1.0", + "datastore-core": "^10.0.2", + "helia": "^5.0.0", + "ipfs-unixfs-importer": "^15.3.1", + "ipns": "^10.0.0", "it-all": "^3.0.6", "it-drain": "^3.0.7", "it-last": "^3.0.6", diff --git a/packages/verified-fetch/src/errors.ts b/packages/verified-fetch/src/errors.ts new file mode 100644 index 00000000..09be1778 --- /dev/null +++ b/packages/verified-fetch/src/errors.ts @@ -0,0 +1,26 @@ +export class InvalidRangeError extends Error { + static name = 'InvalidRangeError' + + constructor (message = 'Invalid range request') { + super(message) + this.name = 'InvalidRangeError' + } +} + +export class NoContentError extends Error { + static name = 'NoContentError' + + constructor (message = 'No content found') { + super(message) + this.name = 'NoContentError' + } +} + +export class SubdomainNotSupportedError extends Error { + static name = 'SubdomainNotSupportedError' + + constructor (message = 'Subdomain not supported') { + super(message) + this.name = 'SubdomainNotSupportedError' + } +} diff --git a/packages/verified-fetch/src/utils/byte-range-context.ts b/packages/verified-fetch/src/utils/byte-range-context.ts index c794d360..702bd991 100644 --- a/packages/verified-fetch/src/utils/byte-range-context.ts +++ b/packages/verified-fetch/src/utils/byte-range-context.ts @@ -1,3 +1,4 @@ +import { InvalidRangeError } from '../errors.js' import { calculateByteRangeIndexes, getHeader } from './request-headers.js' import { getContentRangeHeader } from './response-headers.js' import type { SupportedBodyTypes } from '../types.js' @@ -32,7 +33,7 @@ function getByteRangeFromHeader (rangeHeader: string): { start: string, end: str */ const match = rangeHeader.match(/^bytes=(?\d+)?-(?\d+)?$/) if (match?.groups == null) { - throw new Error('Invalid range request') + throw new InvalidRangeError('Invalid range request') } const { start, end } = match.groups @@ -289,7 +290,7 @@ export class ByteRangeContext { public get contentRangeHeaderValue (): string { if (!this.isValidRangeRequest) { this.log.error('cannot get contentRangeHeaderValue for invalid range request') - throw new Error('Invalid range request') + throw new InvalidRangeError('Invalid range request') } return getContentRangeHeader({ diff --git a/packages/verified-fetch/src/utils/get-stream-from-async-iterable.ts b/packages/verified-fetch/src/utils/get-stream-from-async-iterable.ts index 476276fa..faf3a6d3 100644 --- a/packages/verified-fetch/src/utils/get-stream-from-async-iterable.ts +++ b/packages/verified-fetch/src/utils/get-stream-from-async-iterable.ts @@ -1,5 +1,6 @@ import { AbortError, type ComponentLogger } from '@libp2p/interface' import { CustomProgressEvent } from 'progress-events' +import { NoContentError } from '../errors.js' import type { VerifiedFetchInit } from '../index.js' /** @@ -12,7 +13,7 @@ export async function getStreamFromAsyncIterable (iterator: AsyncIterable & { name: string function toTarImportCandidate (entry: UnixFSEntry): TarImportCandidate { if (!EXPORTABLE.includes(entry.type)) { - throw new CodeError('Not a UnixFS node', 'ERR_NOT_UNIXFS') + throw new NotUnixFSError(`${entry.type} is not a UnixFS node`) } const candidate: TarImportCandidate = { @@ -64,5 +64,5 @@ export async function * tarStream (ipfsPath: string, blockstore: Blockstore, opt return } - throw new CodeError('Not a UnixFS node', 'ERR_NOT_UNIXFS') + throw new NotUnixFSError('Not a UnixFS node') } diff --git a/packages/verified-fetch/src/utils/handle-redirects.ts b/packages/verified-fetch/src/utils/handle-redirects.ts index b1234445..20dfc5c9 100644 --- a/packages/verified-fetch/src/utils/handle-redirects.ts +++ b/packages/verified-fetch/src/utils/handle-redirects.ts @@ -1,4 +1,5 @@ import { type AbortOptions, type ComponentLogger } from '@libp2p/interface' +import { SubdomainNotSupportedError } from '../errors.js' import { type VerifiedFetchInit, type Resource } from '../index.js' import { matchURLString } from './parse-url-string.js' import { movedPermanentlyResponse } from './responses.js' @@ -82,7 +83,7 @@ export async function getRedirectResponse ({ resource, options, logger, cid, fet return movedPermanentlyResponse(resource.toString(), subdomainUrl.href) } else { log('subdomain not supported, subdomain failed with status %s %s', subdomainTest.status, subdomainTest.statusText) - throw new Error('subdomain not supported') + throw new SubdomainNotSupportedError('subdomain not supported') } } catch (err: any) { log('subdomain not supported', err) diff --git a/packages/verified-fetch/src/utils/parse-url-string.ts b/packages/verified-fetch/src/utils/parse-url-string.ts index 65e652b0..afd1ca80 100644 --- a/packages/verified-fetch/src/utils/parse-url-string.ts +++ b/packages/verified-fetch/src/utils/parse-url-string.ts @@ -3,7 +3,7 @@ import { CID } from 'multiformats/cid' import { TLRU } from './tlru.js' import type { RequestFormatShorthand } from '../types.js' import type { DNSLinkResolveResult, IPNS, IPNSResolveResult, IPNSRoutingEvents, ResolveDNSLinkProgressEvents, ResolveProgressEvents, ResolveResult } from '@helia/ipns' -import type { AbortOptions, ComponentLogger } from '@libp2p/interface' +import type { AbortOptions, ComponentLogger, PeerId } from '@libp2p/interface' import type { ProgressOptions } from 'progress-events' const ipnsCache = new TLRU(1000) @@ -174,11 +174,14 @@ export async function parseUrlString ({ urlString, ipns, logger }: ParseUrlStrin log.trace('resolved %s to %c from cache', cidOrPeerIdOrDnsLink, cid) } else { log.trace('Attempting to resolve PeerId for %s', cidOrPeerIdOrDnsLink) - let peerId = null + let peerId: PeerId | undefined try { // try resolving as an IPNS name peerId = peerIdFromString(cidOrPeerIdOrDnsLink) - resolveResult = await ipns.resolve(peerId, options) + if (peerId.publicKey == null) { + throw new TypeError('cidOrPeerIdOrDnsLink contains no public key') + } + resolveResult = await ipns.resolve(peerId.publicKey, options) cid = resolveResult?.cid resolvedPath = resolveResult?.path log.trace('resolved %s to %c', cidOrPeerIdOrDnsLink, cid) diff --git a/packages/verified-fetch/src/utils/request-headers.ts b/packages/verified-fetch/src/utils/request-headers.ts index 33a93705..34cdea69 100644 --- a/packages/verified-fetch/src/utils/request-headers.ts +++ b/packages/verified-fetch/src/utils/request-headers.ts @@ -1,3 +1,5 @@ +import { InvalidRangeError } from '../errors.js' + export function getHeader (headers: HeadersInit | undefined, header: string): string | undefined { if (headers == null) { return undefined @@ -26,16 +28,16 @@ export function getHeader (headers: HeadersInit | undefined, header: string): st // eslint-disable-next-line complexity export function calculateByteRangeIndexes (start: number | undefined, end: number | undefined, fileSize?: number): { byteSize?: number, start?: number, end?: number } { if ((start ?? 0) > (end ?? Infinity)) { - throw new Error('Invalid range: Range-start index is greater than range-end index.') + throw new InvalidRangeError('Invalid range: Range-start index is greater than range-end index.') } if (start != null && (end ?? 0) >= (fileSize ?? Infinity)) { - throw new Error('Invalid range: Range-end index is greater than or equal to the size of the file.') + throw new InvalidRangeError('Invalid range: Range-end index is greater than or equal to the size of the file.') } if (start == null && (end ?? 0) > (fileSize ?? Infinity)) { - throw new Error('Invalid range: Range-end index is greater than the size of the file.') + throw new InvalidRangeError('Invalid range: Range-end index is greater than the size of the file.') } if (start != null && start < 0) { - throw new Error('Invalid range: Range-start index cannot be negative.') + throw new InvalidRangeError('Invalid range: Range-start index cannot be negative.') } if (start != null && end != null) { diff --git a/packages/verified-fetch/src/utils/response-headers.ts b/packages/verified-fetch/src/utils/response-headers.ts index 0a2b5b26..c691d1c5 100644 --- a/packages/verified-fetch/src/utils/response-headers.ts +++ b/packages/verified-fetch/src/utils/response-headers.ts @@ -1,3 +1,4 @@ +import { InvalidRangeError } from '../errors.js' import type { CID } from 'multiformats/cid' interface CacheControlHeaderOptions { @@ -46,10 +47,10 @@ export function getContentRangeHeader ({ byteStart, byteEnd, byteSize }: { byteS const total = byteSize ?? '*' // if we don't know the total size, we should use * if ((byteEnd ?? 0) >= (byteSize ?? Infinity)) { - throw new Error('Invalid range: Range-end index is greater than or equal to the size of the file.') + throw new InvalidRangeError('Invalid range: Range-end index is greater than or equal to the size of the file.') } if ((byteStart ?? 0) >= (byteSize ?? Infinity)) { - throw new Error('Invalid range: Range-start index is greater than or equal to the size of the file.') + throw new InvalidRangeError('Invalid range: Range-start index is greater than or equal to the size of the file.') } if (byteStart != null && byteEnd == null) { diff --git a/packages/verified-fetch/src/utils/walk-path.ts b/packages/verified-fetch/src/utils/walk-path.ts index 62b52ceb..44922d07 100644 --- a/packages/verified-fetch/src/utils/walk-path.ts +++ b/packages/verified-fetch/src/utils/walk-path.ts @@ -1,4 +1,5 @@ -import { CodeError, type Logger } from '@libp2p/interface' +import { DoesNotExistError } from '@helia/unixfs/errors' +import { type Logger } from '@libp2p/interface' import { type Blockstore } from 'interface-blockstore' import { walkPath as exporterWalk, type ExporterOptions, type ReadableStorage, type ObjectNode, type UnixFSEntry } from 'ipfs-unixfs-exporter' import { type FetchHandlerFunctionArg } from '../types.js' @@ -28,7 +29,7 @@ export async function walkPath (blockstore: ReadableStorage, path: string, optio } if (terminalElement == null) { - throw new CodeError('No terminal element found', 'ERR_NO_TERMINAL_ELEMENT') + throw new DoesNotExistError('No terminal element found') } return { diff --git a/packages/verified-fetch/src/verified-fetch.ts b/packages/verified-fetch/src/verified-fetch.ts index 2ca99392..07516010 100644 --- a/packages/verified-fetch/src/verified-fetch.ts +++ b/packages/verified-fetch/src/verified-fetch.ts @@ -32,7 +32,7 @@ import { setCacheControlHeader, setIpfsRoots } from './utils/response-headers.js import { badRequestResponse, movedPermanentlyResponse, notAcceptableResponse, notSupportedResponse, okResponse, badRangeResponse, okRangeResponse, badGatewayResponse, notFoundResponse } from './utils/responses.js' import { selectOutputType } from './utils/select-output-type.js' import { handlePathWalking, isObjectNode } from './utils/walk-path.js' -import type { CIDDetail, ContentTypeParser, CreateVerifiedFetchOptions, Resource, VerifiedFetchInit as VerifiedFetchOptions } from './index.js' +import type { CIDDetail, ContentTypeParser, CreateVerifiedFetchOptions, Resource, ResourceDetail, VerifiedFetchInit as VerifiedFetchOptions } from './index.js' import type { FetchHandlerFunctionArg, RequestFormatShorthand } from './types.js' import type { Helia, SessionBlockstore } from '@helia/interface' import type { Blockstore } from 'interface-blockstore' @@ -167,7 +167,7 @@ export class VerifiedFetch { // just read it out.. const routingKey = uint8ArrayConcat([ uint8ArrayFromString('/ipns/'), - peerId.toBytes() + peerId.toMultihash().bytes ]) const datastoreKey = new Key('/dht/record/' + uint8ArrayToString(routingKey, 'base32'), false) const buf = await this.helia.datastore.get(datastoreKey, options) @@ -185,7 +185,7 @@ export class VerifiedFetch { */ private async handleCar ({ resource, cid, session, options }: FetchHandlerFunctionArg): Promise { const blockstore = this.getBlockstore(cid, resource, session, options) - const c = car({ blockstore, dagWalkers: this.helia.dagWalkers }) + const c = car({ blockstore, getCodec: this.helia.getCodec }) const stream = toBrowserReadableStream(c.stream(cid, options)) const response = okResponse(resource, stream) @@ -481,8 +481,7 @@ export class VerifiedFetch { const options = convertOptions(opts) - options?.onProgress?.(new CustomProgressEvent('verified-fetch:request:start', { resource })) - + options?.onProgress?.(new CustomProgressEvent('verified-fetch:request:start', { resource })) // resolve the CID/path from the requested resource let cid: ParsedUrlStringResults['cid'] let path: ParsedUrlStringResults['path'] diff --git a/packages/verified-fetch/test/abort-handling.spec.ts b/packages/verified-fetch/test/abort-handling.spec.ts index 972ba719..0106c5de 100644 --- a/packages/verified-fetch/test/abort-handling.spec.ts +++ b/packages/verified-fetch/test/abort-handling.spec.ts @@ -1,9 +1,10 @@ import { dagCbor } from '@helia/dag-cbor' import { type DNSLinkResolveResult, type IPNS, type IPNSResolveResult } from '@helia/ipns' import { unixfs } from '@helia/unixfs' +import { generateKeyPair } from '@libp2p/crypto/keys' import { stop, type ComponentLogger, type Logger } from '@libp2p/interface' import { prefixLogger, logger as libp2pLogger } from '@libp2p/logger' -import { createEd25519PeerId } from '@libp2p/peer-id-factory' +import { peerIdFromPrivateKey } from '@libp2p/peer-id' import { expect } from 'aegir/chai' import browserReadableStreamToIt from 'browser-readablestream-to-it' import { fixedSize } from 'ipfs-unixfs-importer/chunker' @@ -102,11 +103,12 @@ describe('abort-handling', function () { hello: 'world' }) - const peerId = await createEd25519PeerId() + const key = await generateKeyPair('Ed25519') + const peerId = peerIdFromPrivateKey(key) - await name.publish(peerId, cid, { lifetime: 1000 * 60 * 60 }) + await name.publish(key, cid, { lifetime: 1000 * 60 * 60 }) - await expect(makeAbortedRequest(verifiedFetch, [`ipns://${peerId}`], peerIdResolverCalled.promise)).to.eventually.be.rejectedWith('aborted') + await expect(makeAbortedRequest(verifiedFetch, [`ipns://${peerId.toString()}`], peerIdResolverCalled.promise)).to.eventually.be.rejectedWith('aborted') expect(peerIdResolver.callCount).to.equal(1) expect(dnsLinkResolver.callCount).to.equal(0) // not called because signal abort was detected expect(blockRetriever.retrieve.callCount).to.equal(0) // not called because we never got the cid diff --git a/packages/verified-fetch/test/accept-header.spec.ts b/packages/verified-fetch/test/accept-header.spec.ts index f255be31..0205b331 100644 --- a/packages/verified-fetch/test/accept-header.spec.ts +++ b/packages/verified-fetch/test/accept-header.spec.ts @@ -3,11 +3,12 @@ import { dagJson } from '@helia/dag-json' import { ipns } from '@helia/ipns' import * as ipldDagCbor from '@ipld/dag-cbor' import * as ipldDagJson from '@ipld/dag-json' +import { generateKeyPair } from '@libp2p/crypto/keys' import { stop } from '@libp2p/interface' -import { createEd25519PeerId } from '@libp2p/peer-id-factory' +import { peerIdFromPrivateKey } from '@libp2p/peer-id' import { expect } from 'aegir/chai' import * as cborg from 'cborg' -import { marshal } from 'ipns' +import { marshalIPNSRecord } from 'ipns' import { CID } from 'multiformats/cid' import * as raw from 'multiformats/codecs/raw' import { sha256 } from 'multiformats/hashes/sha2' @@ -269,7 +270,9 @@ describe('accept header', () => { }) it('should support fetching IPNS records', async () => { - const peerId = await createEd25519PeerId() + const key = await generateKeyPair('Ed25519') + const peerId = peerIdFromPrivateKey(key) + const obj = { hello: 'world' } @@ -277,7 +280,7 @@ describe('accept header', () => { const cid = await c.add(obj) const i = ipns(helia) - const record = await i.publish(peerId, cid) + const record = await i.publish(key, cid) const resp = await verifiedFetch.fetch(`ipns://${peerId}`, { headers: { @@ -288,7 +291,7 @@ describe('accept header', () => { expect(resp.headers.get('content-type')).to.equal('application/vnd.ipfs.ipns-record') const buf = await resp.arrayBuffer() - expect(new Uint8Array(buf)).to.equalBytes(marshal(record)) + expect(new Uint8Array(buf)).to.equalBytes(marshalIPNSRecord(record)) }) shouldNotAcceptCborWith({ diff --git a/packages/verified-fetch/test/cache-control-header.spec.ts b/packages/verified-fetch/test/cache-control-header.spec.ts index a6eb2b76..feae91c0 100644 --- a/packages/verified-fetch/test/cache-control-header.spec.ts +++ b/packages/verified-fetch/test/cache-control-header.spec.ts @@ -1,7 +1,8 @@ import { dagCbor } from '@helia/dag-cbor' import { ipns } from '@helia/ipns' +import { generateKeyPair } from '@libp2p/crypto/keys' import { stop } from '@libp2p/interface' -import { createEd25519PeerId } from '@libp2p/peer-id-factory' +import { peerIdFromPrivateKey } from '@libp2p/peer-id' import { dns } from '@multiformats/dns' import { expect } from 'aegir/chai' import Sinon from 'sinon' @@ -59,10 +60,11 @@ describe('cache-control header', () => { const cid = await c.add(obj) const oneHourInMs = 1000 * 60 * 60 - const peerId = await createEd25519PeerId() + const key = await generateKeyPair('Ed25519') + const peerId = peerIdFromPrivateKey(key) // ipns currently only allows customising the lifetime which is also used as the TTL - await name.publish(peerId, cid, { lifetime: oneHourInMs }) + await name.publish(key, cid, { lifetime: oneHourInMs }) const resp = await verifiedFetch.fetch(`ipns://${peerId}`) expect(resp).to.be.ok() @@ -82,7 +84,8 @@ describe('cache-control header', () => { const cid = await c.add(obj) const oneHourInSeconds = 60 * 60 - const peerId = await createEd25519PeerId() + const key = await generateKeyPair('Ed25519') + const peerId = peerIdFromPrivateKey(key) /** * ipns currently only allows customising the lifetime which is also used as the TTL @@ -92,7 +95,7 @@ describe('cache-control header', () => { * @see https://github.com/ipfs/js-ipns/blob/16e0e10682fa9a663e0bb493a44d3e99a5200944/src/index.ts#L200 * @see https://github.com/ipfs/js-ipns/pull/308 */ - await name.publish(peerId, cid, { lifetime: oneHourInSeconds * 1000 }) // pass to ipns as milliseconds + await name.publish(key, cid, { lifetime: oneHourInSeconds * 1000 }) // pass to ipns as milliseconds const resp = await verifiedFetch.fetch(`ipns://${peerId}`) expect(resp).to.be.ok() diff --git a/packages/verified-fetch/test/ipns-record.spec.ts b/packages/verified-fetch/test/ipns-record.spec.ts index a101d7ca..04c8412e 100644 --- a/packages/verified-fetch/test/ipns-record.spec.ts +++ b/packages/verified-fetch/test/ipns-record.spec.ts @@ -1,9 +1,10 @@ import { dagCbor } from '@helia/dag-cbor' import { ipns } from '@helia/ipns' +import { generateKeyPair } from '@libp2p/crypto/keys' import { stop } from '@libp2p/interface' -import { createEd25519PeerId } from '@libp2p/peer-id-factory' +import { peerIdFromPrivateKey } from '@libp2p/peer-id' import { expect } from 'aegir/chai' -import { marshal, unmarshal } from 'ipns' +import { marshalIPNSRecord, unmarshalIPNSRecord } from 'ipns' import { VerifiedFetch } from '../src/verified-fetch.js' import { createHelia } from './fixtures/create-offline-helia.js' import type { Helia } from '@helia/interface' @@ -33,8 +34,9 @@ describe('ipns records', () => { const c = dagCbor(helia) const cid = await c.add(obj) - const peerId = await createEd25519PeerId() - const record = await name.publish(peerId, cid) + const key = await generateKeyPair('Ed25519') + const peerId = peerIdFromPrivateKey(key) + const record = await name.publish(key, cid) const resp = await verifiedFetch.fetch(`ipns://${peerId}`, { headers: { @@ -45,9 +47,9 @@ describe('ipns records', () => { expect(resp.headers.get('content-type')).to.equal('application/vnd.ipfs.ipns-record') const buf = new Uint8Array(await resp.arrayBuffer()) - expect(marshal(record)).to.equalBytes(buf) + expect(marshalIPNSRecord(record)).to.equalBytes(buf) - const output = unmarshal(buf) + const output = unmarshalIPNSRecord(buf) expect(output.value).to.deep.equal(`/ipfs/${cid}`) }) @@ -76,8 +78,9 @@ describe('ipns records', () => { const c = dagCbor(helia) const cid = await c.add(obj) - const peerId = await createEd25519PeerId() - await name.publish(peerId, cid) + const key = await generateKeyPair('Ed25519') + const peerId = peerIdFromPrivateKey(key) + await name.publish(key, cid) const resp = await verifiedFetch.fetch(`ipns://${peerId}/hello`, { headers: { diff --git a/packages/verified-fetch/test/parse-resource.spec.ts b/packages/verified-fetch/test/parse-resource.spec.ts index e903a0aa..d6f92c23 100644 --- a/packages/verified-fetch/test/parse-resource.spec.ts +++ b/packages/verified-fetch/test/parse-resource.spec.ts @@ -1,5 +1,6 @@ +import { generateKeyPair } from '@libp2p/crypto/keys' import { defaultLogger } from '@libp2p/logger' -import { createEd25519PeerId } from '@libp2p/peer-id-factory' +import { peerIdFromPrivateKey } from '@libp2p/peer-id' import { expect } from 'aegir/chai' import { CID } from 'multiformats/cid' import sinon from 'sinon' @@ -8,7 +9,8 @@ import { parseResource } from '../src/utils/parse-resource.js' import type { IPNS } from '@helia/ipns' const testCID = CID.parse('QmQJ8fxavY54CUsxMSx9aE9Rdcmvhx8awJK2jzJp4iAqCr') -const peerId = await createEd25519PeerId() +const key = await generateKeyPair('Ed25519') +const peerId = peerIdFromPrivateKey(key) describe('parseResource', () => { it('does not call @helia/ipns for CID', async () => { diff --git a/packages/verified-fetch/test/utils/parse-url-string.spec.ts b/packages/verified-fetch/test/utils/parse-url-string.spec.ts index 08e2a49d..54edfcf6 100644 --- a/packages/verified-fetch/test/utils/parse-url-string.spec.ts +++ b/packages/verified-fetch/test/utils/parse-url-string.spec.ts @@ -1,6 +1,7 @@ +import { generateKeyPair } from '@libp2p/crypto/keys' import { matchPeerId } from '@libp2p/interface-compliance-tests/matchers' import { defaultLogger } from '@libp2p/logger' -import { createEd25519PeerId } from '@libp2p/peer-id-factory' +import { peerIdFromPrivateKey } from '@libp2p/peer-id' import { type Answer } from '@multiformats/dns' import { expect } from 'aegir/chai' import { CID } from 'multiformats/cid' @@ -75,7 +76,7 @@ describe('parseUrlString', () => { ipns, logger }) - ).to.eventually.be.rejected.with.property('message', 'Could not parse PeerId in ipns url "mydomain.com", Non-base64 character') + ).to.eventually.be.rejected.with.property('message', 'Could not parse PeerId in ipns url "mydomain.com", Please pass a multibase decoder for strings that do not start with "1" or "Q"') }) }) @@ -160,7 +161,7 @@ describe('parseUrlString', () => { await expect(parseUrlString({ urlString: 'ipns://mydomain.com', ipns, logger })).to.eventually.be.rejected .with.property('errors').that.deep.equals([ - new TypeError('Could not parse PeerId in ipns url "mydomain.com", Non-base64 character'), + new TypeError('Could not parse PeerId in ipns url "mydomain.com", Please pass a multibase decoder for strings that do not start with "1" or "Q"'), new Error('Unexpected failure from ipns dns query') ]) }) @@ -278,7 +279,8 @@ describe('parseUrlString', () => { }) it('should return the correct TTL from the IPNS answer', async () => { - const testPeerId = await createEd25519PeerId() + const key = await generateKeyPair('Ed25519') + const testPeerId = peerIdFromPrivateKey(key) ipns.resolve.withArgs(matchPeerId(testPeerId)).resolves({ cid: CID.parse('QmQJ8fxavY54CUsxMSx9aE9Rdcmvhx8awJK2jzJp4iAqCr'), @@ -459,7 +461,8 @@ describe('parseUrlString', () => { let testPeerId: PeerId beforeEach(async () => { - testPeerId = await createEd25519PeerId() + const key = await generateKeyPair('Ed25519') + testPeerId = peerIdFromPrivateKey(key) }) it('handles invalid PeerIds', async () => { @@ -575,7 +578,8 @@ describe('parseUrlString', () => { it('should parse an ipns:// url with a path that resolves to a CID with a path', async () => { const cid = CID.parse('QmQJ8fxavY54CUsxMSx9aE9Rdcmvhx8awJK2jzJp4iAqCr') - const peerId = await createEd25519PeerId() + const key = await generateKeyPair('Ed25519') + const peerId = peerIdFromPrivateKey(key) const recordPath = 'foo' const requestPath = 'bar/baz.txt' @@ -597,7 +601,8 @@ describe('parseUrlString', () => { it('should parse an ipns:// url with a path that resolves to a CID with a path with a trailing slash', async () => { const cid = CID.parse('QmQJ8fxavY54CUsxMSx9aE9Rdcmvhx8awJK2jzJp4iAqCr') - const peerId = await createEd25519PeerId() + const key = await generateKeyPair('Ed25519') + const peerId = peerIdFromPrivateKey(key) const recordPath = 'foo/' const requestPath = 'bar/baz.txt' @@ -619,7 +624,8 @@ describe('parseUrlString', () => { it('should parse an ipns:// url with a path that resolves to a CID with a path with a trailing slash', async () => { const cid = CID.parse('QmQJ8fxavY54CUsxMSx9aE9Rdcmvhx8awJK2jzJp4iAqCr') - const peerId = await createEd25519PeerId() + const key = await generateKeyPair('Ed25519') + const peerId = peerIdFromPrivateKey(key) const recordPath = '/foo/////bar//' const requestPath = '///baz///qux.txt' @@ -645,7 +651,8 @@ describe('parseUrlString', () => { let cid: CID beforeEach(async () => { - peerId = await createEd25519PeerId() + const key = await generateKeyPair('Ed25519') + peerId = peerIdFromPrivateKey(key) cid = CID.parse('QmdmQXB2mzChmMeKY47C43LxUdg1NDJ5MWcKMKxDu7RgQm') ipns.resolve.withArgs(matchPeerId(peerId)).resolves({ cid, @@ -733,7 +740,8 @@ describe('parseUrlString', () => { let cid: CID beforeEach(async () => { - peerId = await createEd25519PeerId() + const key = await generateKeyPair('Ed25519') + peerId = peerIdFromPrivateKey(key) cid = CID.parse('QmdmQXB2mzChmMeKY47C43LxUdg1NDJ5MWcKMKxDu7RgQm') ipns.resolve.withArgs(matchPeerId(peerId)).resolves({ cid, @@ -819,7 +827,10 @@ describe('parseUrlString', () => { const IPNS_TYPES = [ ['dnslink-encoded', (i: number) => `${i}-example-com`], ['dnslink-decoded', (i: number) => `${i}.example.com`], - ['peerid', async () => createEd25519PeerId()] + ['peerid', async () => { + const key = await generateKeyPair('Ed25519') + return peerIdFromPrivateKey(key) + }] ] as const IPNS_TYPES.flatMap(([type, fn]) => {