Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@
},
"dependencies": {
"@fastify/cors": "^8.3.0",
"@helia/interface": "^2.0.0",
"@libp2p/interface": "^0.1.2",
"@libp2p/peer-id": "^3.0.3",
"fastify": "^4.17.0",
Expand All @@ -160,6 +159,7 @@
"raw-body": "^2.5.2"
},
"devDependencies": {
"@helia/interface": "^2.0.0",
"@libp2p/peer-id-factory": "^3.0.5",
"@multiformats/multiaddr": "^12.1.3",
"@types/sinon": "^17.0.0",
Expand Down
6 changes: 3 additions & 3 deletions packages/server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ import fastify, {
type FastifyInstance
} from 'fastify'
import routes from './routes/index.js'
import type { Helia } from '@helia/interface'
import type { Libp2p } from '@libp2p/interface'

export interface ServerInit {
fastify?: FastifyInstance
Expand All @@ -67,15 +67,15 @@ export interface ServerInit {
/**
* Create and return a Routing V1 HTTP API server
*/
export async function createDelegatedRoutingV1HttpApiServer (helia: Helia, init: ServerInit = {}): Promise<FastifyInstance> {
export async function createDelegatedRoutingV1HttpApiServer (helia: { libp2p: Libp2p }, init: ServerInit = {}): Promise<FastifyInstance> {
const server = init.fastify ?? fastify()
await server.register(cors, {
origin: '*',
methods: ['GET', 'OPTIONS'],
strictPreflight: false
})

routes(server, helia)
routes(server, helia.libp2p)

await server.listen(init.listen ?? {
port: 0
Expand Down
12 changes: 6 additions & 6 deletions packages/server/src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ import getIpnsV1 from './routing/v1/ipns/get.js'
import putIpnsV1 from './routing/v1/ipns/put.js'
import getPeersV1 from './routing/v1/peers/get.js'
import getProvidersV1 from './routing/v1/providers/get.js'
import type { Helia } from '@helia/interface'
import type { Libp2p } from '@libp2p/interface'
import type { FastifyInstance } from 'fastify'

export default function routes (fastify: FastifyInstance, helia: Helia): void {
getProvidersV1(fastify, helia)
getPeersV1(fastify, helia)
getIpnsV1(fastify, helia)
putIpnsV1(fastify, helia)
export default function routes (fastify: FastifyInstance, libp2p: Libp2p): void {
getProvidersV1(fastify, libp2p)
getPeersV1(fastify, libp2p)
getIpnsV1(fastify, libp2p)
putIpnsV1(fastify, libp2p)
}
6 changes: 3 additions & 3 deletions packages/server/src/routes/routing/v1/ipns/get.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { peerIdFromCID } from '@libp2p/peer-id'
import { peerIdToRoutingKey } from 'ipns'
import { CID } from 'multiformats/cid'
import type { Helia } from '@helia/interface'
import type { Libp2p } from '@libp2p/interface'
import type { PeerId } from '@libp2p/interface/peer-id'
import type { FastifyInstance } from 'fastify'

interface Params {
name: string
}

export default function getIpnsV1 (fastify: FastifyInstance, helia: Helia): void {
export default function getIpnsV1 (fastify: FastifyInstance, libp2p: Libp2p): void {
fastify.route<{ Params: Params }>({
method: 'GET',
url: '/routing/v1/ipns/:name',
Expand Down Expand Up @@ -43,7 +43,7 @@ export default function getIpnsV1 (fastify: FastifyInstance, helia: Helia): void
return reply.code(422).type('text/html').send('Unprocessable Entity')
}

const rawRecord = await helia.libp2p.contentRouting.get(peerIdToRoutingKey(peerId), {
const rawRecord = await libp2p.contentRouting.get(peerIdToRoutingKey(peerId), {
signal: controller.signal
})

Expand Down
6 changes: 3 additions & 3 deletions packages/server/src/routes/routing/v1/ipns/put.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import { peerIdToRoutingKey } from 'ipns'
import { ipnsValidator } from 'ipns/validator'
import { CID } from 'multiformats/cid'
import getRawBody from 'raw-body'
import type { Helia } from '@helia/interface'
import type { Libp2p } from '@libp2p/interface'
import type { PeerId } from '@libp2p/interface/peer-id'
import type { FastifyInstance } from 'fastify'

interface Params {
name: string
}

export default function putIpnsV1 (fastify: FastifyInstance, helia: Helia): void {
export default function putIpnsV1 (fastify: FastifyInstance, libp2p: Libp2p): void {
fastify.addContentTypeParser('application/vnd.ipfs.ipns-record', function (request, payload, done) {
getRawBody(payload)
.then(buff => { done(null, buff) })
Expand Down Expand Up @@ -55,7 +55,7 @@ export default function putIpnsV1 (fastify: FastifyInstance, helia: Helia): void
const body: Uint8Array = request.body
await ipnsValidator(peerIdToRoutingKey(peerId), body)

await helia.libp2p.contentRouting.put(peerIdToRoutingKey(peerId), body, {
await libp2p.contentRouting.put(peerIdToRoutingKey(peerId), body, {
signal: controller.signal
})

Expand Down
6 changes: 3 additions & 3 deletions packages/server/src/routes/routing/v1/peers/get.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { PassThrough } from 'node:stream'
import { peerIdFromCID } from '@libp2p/peer-id'
import { CID } from 'multiformats/cid'
import type { Helia } from '@helia/interface'
import type { Libp2p } from '@libp2p/interface'
import type { PeerId } from '@libp2p/interface/peer-id'
import type { FastifyInstance } from 'fastify'

interface Params {
peerId: string
}

export default function getPeersV1 (fastify: FastifyInstance, helia: Helia): void {
export default function getPeersV1 (fastify: FastifyInstance, libp2p: Libp2p): void {
fastify.route<{ Params: Params }>({
method: 'GET',
url: '/routing/v1/peers/:peerId',
Expand Down Expand Up @@ -42,7 +42,7 @@ export default function getPeersV1 (fastify: FastifyInstance, helia: Helia): voi
return reply.code(422).type('text/html').send('Unprocessable Entity')
}

const peerInfo = await helia.libp2p.peerRouting.findPeer(peerId, {
const peerInfo = await libp2p.peerRouting.findPeer(peerId, {
signal: controller.signal
})
const peerRecord = {
Expand Down
17 changes: 8 additions & 9 deletions packages/server/src/routes/routing/v1/providers/get.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { PassThrough } from 'node:stream'
import { CID } from 'multiformats/cid'
import type { Helia } from '@helia/interface'
import type { AbortOptions } from '@libp2p/interface'
import type { AbortOptions, Libp2p } from '@libp2p/interface'
import type { FastifyInstance } from 'fastify'

interface Params {
Expand All @@ -21,7 +20,7 @@ interface Providers {

const MAX_PROVIDERS = 100

export default function getProvidersV1 (fastify: FastifyInstance, helia: Helia): void {
export default function getProvidersV1 (fastify: FastifyInstance, libp2p: Libp2p): void {
fastify.route<{ Params: Params }>({
method: 'GET',
url: '/routing/v1/providers/:cid',
Expand Down Expand Up @@ -57,7 +56,7 @@ export default function getProvidersV1 (fastify: FastifyInstance, helia: Helia):
const stream = new PassThrough()

// wait until we have the first result
const iterable = streamingHandler(cid, helia, {
const iterable = streamingHandler(cid, libp2p, {
signal: controller.signal
})
const result = await iterable.next()
Expand All @@ -84,7 +83,7 @@ export default function getProvidersV1 (fastify: FastifyInstance, helia: Helia):
.send(stream)
}
} else {
const result = await nonStreamingHandler(cid, helia, {
const result = await nonStreamingHandler(cid, libp2p, {
signal: controller.signal
})

Expand All @@ -98,10 +97,10 @@ export default function getProvidersV1 (fastify: FastifyInstance, helia: Helia):
})
}

async function * streamingHandler (cid: CID, helia: Helia, options?: AbortOptions): AsyncGenerator<PeerRecord, void, unknown> {
async function * streamingHandler (cid: CID, libp2p: Libp2p, options?: AbortOptions): AsyncGenerator<PeerRecord, void, unknown> {
let provs = 0

for await (const prov of helia.libp2p.contentRouting.findProviders(cid, options)) {
for await (const prov of libp2p.contentRouting.findProviders(cid, options)) {
yield {
Schema: 'peer',
ID: prov.id.toString(),
Expand All @@ -116,11 +115,11 @@ async function * streamingHandler (cid: CID, helia: Helia, options?: AbortOption
}
}

async function nonStreamingHandler (cid: CID, helia: Helia, options?: AbortOptions): Promise<Providers> {
async function nonStreamingHandler (cid: CID, libp2p: Libp2p, options?: AbortOptions): Promise<Providers> {
const providers = []

try {
for await (const prov of helia.libp2p.contentRouting.findProviders(cid, options)) {
for await (const prov of libp2p.contentRouting.findProviders(cid, options)) {
providers.push({
Schema: 'peer',
ID: prov.id.toString(),
Expand Down
70 changes: 19 additions & 51 deletions packages/server/test/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { CID } from 'multiformats'
import { stubInterface } from 'sinon-ts'
import { createDelegatedRoutingV1HttpApiServer } from '../src/index.js'
import type { Helia } from '@helia/interface'
import type { Libp2p } from '@libp2p/interface'
import type { PeerInfo } from '@libp2p/interface/peer-info'
import type { FastifyInstance } from 'fastify'
import type { StubbedInstance } from 'sinon-ts'
Expand All @@ -18,7 +19,9 @@ describe('delegated-routing-v1-http-api-server', () => {
let url: URL

beforeEach(async () => {
helia = stubInterface<Helia>()
helia = stubInterface<Helia>({
libp2p: stubInterface<Libp2p>()
})
server = await createDelegatedRoutingV1HttpApiServer(helia, {
listen: {
host: '127.0.0.1',
Expand Down Expand Up @@ -66,12 +69,7 @@ describe('delegated-routing-v1-http-api-server', () => {
})

it('GET providers returns 404 if no providers are found', async () => {
helia.libp2p = {
// @ts-expect-error incomplete implementation
contentRouting: {
findProviders: async function * () {}
}
}
helia.libp2p.contentRouting.findProviders = async function * () {}

const res = await fetch(`${url}routing/v1/providers/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn`, {
method: 'GET'
Expand All @@ -81,12 +79,7 @@ describe('delegated-routing-v1-http-api-server', () => {
})

it('GET providers returns 404 if no providers are found when streaming', async () => {
helia.libp2p = {
// @ts-expect-error incomplete implementation
contentRouting: {
findProviders: async function * () {}
}
}
helia.libp2p.contentRouting.findProviders = async function * () {}

const res = await fetch(`${url}routing/v1/providers/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn`, {
method: 'GET',
Expand Down Expand Up @@ -114,14 +107,9 @@ describe('delegated-routing-v1-http-api-server', () => {
protocols: []
}

helia.libp2p = {
// @ts-expect-error incomplete implementation
contentRouting: {
findProviders: async function * () {
yield provider1
yield provider2
}
}
helia.libp2p.contentRouting.findProviders = async function * () {
yield provider1
yield provider2
}

const res = await fetch(`${url}routing/v1/providers/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn`, {
Expand Down Expand Up @@ -156,14 +144,9 @@ describe('delegated-routing-v1-http-api-server', () => {
protocols: []
}

helia.libp2p = {
// @ts-expect-error incomplete implementation
contentRouting: {
findProviders: async function * () {
yield provider1
yield provider2
}
}
helia.libp2p.contentRouting.findProviders = async function * () {
yield provider1
yield provider2
}

const res = await fetch(`${url}routing/v1/providers/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn`, {
Expand Down Expand Up @@ -213,13 +196,8 @@ describe('delegated-routing-v1-http-api-server', () => {
protocols: ['transport-bitswap']
}

helia.libp2p = {
// @ts-expect-error incomplete implementation
peerRouting: {
findPeer: async function () {
return peer
}
}
helia.libp2p.peerRouting.findPeer = async function () {
return peer
}

const res = await fetch(`${url}routing/v1/peers/${peer.id.toCID().toString()}`, {
Expand Down Expand Up @@ -254,13 +232,8 @@ describe('delegated-routing-v1-http-api-server', () => {
const cid = CID.parse('bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4')
const record = await createIpnsRecord(peerId, cid, 0, 1000)

helia.libp2p = {
// @ts-expect-error incomplete implementation
contentRouting: {
get: async function () {
return marshalIpnsRecord(record)
}
}
helia.libp2p.contentRouting.get = async function () {
return marshalIpnsRecord(record)
}

const res = await fetch(`${url}routing/v1/ipns/${peerId.toCID().toString()}`, {
Expand All @@ -284,14 +257,9 @@ describe('delegated-routing-v1-http-api-server', () => {
let putKey: Uint8Array = new Uint8Array()
let putValue: Uint8Array = new Uint8Array()

helia.libp2p = {
// @ts-expect-error incomplete implementation
contentRouting: {
put: async function (key: Uint8Array, value: Uint8Array) {
putKey = key
putValue = value
}
}
helia.libp2p.contentRouting.put = async function (key: Uint8Array, value: Uint8Array) {
putKey = key
putValue = value
}

const res = await fetch(`${url}routing/v1/ipns/${peerId.toCID().toString()}`, {
Expand Down