@helia/delegated-routing-v1-http-api-client 6.0.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/index.min.js +1 -15
- package/dist/index.min.js.map +4 -4
- package/dist/src/client.d.ts +6 -12
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/client.js +42 -45
- package/dist/src/client.js.map +1 -1
- package/dist/src/constants.d.ts +2 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +2 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/index.d.ts +11 -18
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +8 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/routings.d.ts +11 -4
- package/dist/src/routings.d.ts.map +1 -1
- package/dist/src/routings.js +36 -14
- package/dist/src/routings.js.map +1 -1
- package/dist/typedoc-urls.json +7 -3
- package/package.json +8 -7
- package/src/client.ts +47 -54
- package/src/constants.ts +1 -0
- package/src/index.ts +19 -20
- package/src/routings.ts +45 -19
package/dist/typedoc-urls.json
CHANGED
|
@@ -7,16 +7,20 @@
|
|
|
7
7
|
".:DelegatedRoutingV1HttpApiClientInit": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/interfaces/_helia_delegated-routing-v1-http-api-client.DelegatedRoutingV1HttpApiClientInit.html",
|
|
8
8
|
"FilterOptions": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/interfaces/_helia_delegated-routing-v1-http-api-client.FilterOptions.html",
|
|
9
9
|
".:FilterOptions": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/interfaces/_helia_delegated-routing-v1-http-api-client.FilterOptions.html",
|
|
10
|
-
"GetIPNSOptions": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/interfaces/_helia_delegated-routing-v1-http-api-client.GetIPNSOptions.html",
|
|
11
|
-
".:GetIPNSOptions": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/interfaces/_helia_delegated-routing-v1-http-api-client.GetIPNSOptions.html",
|
|
12
10
|
"PeerRecord": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/interfaces/_helia_delegated-routing-v1-http-api-client.PeerRecord.html",
|
|
13
11
|
".:PeerRecord": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/interfaces/_helia_delegated-routing-v1-http-api-client.PeerRecord.html",
|
|
14
12
|
"GetClosestPeersOptions": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/types/_helia_delegated-routing-v1-http-api-client.GetClosestPeersOptions.html",
|
|
15
13
|
".:GetClosestPeersOptions": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/types/_helia_delegated-routing-v1-http-api-client.GetClosestPeersOptions.html",
|
|
14
|
+
"GetIPNSOptions": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/types/_helia_delegated-routing-v1-http-api-client.GetIPNSOptions.html",
|
|
15
|
+
".:GetIPNSOptions": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/types/_helia_delegated-routing-v1-http-api-client.GetIPNSOptions.html",
|
|
16
16
|
"GetPeersOptions": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/types/_helia_delegated-routing-v1-http-api-client.GetPeersOptions.html",
|
|
17
17
|
".:GetPeersOptions": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/types/_helia_delegated-routing-v1-http-api-client.GetPeersOptions.html",
|
|
18
18
|
"GetProvidersOptions": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/types/_helia_delegated-routing-v1-http-api-client.GetProvidersOptions.html",
|
|
19
19
|
".:GetProvidersOptions": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/types/_helia_delegated-routing-v1-http-api-client.GetProvidersOptions.html",
|
|
20
20
|
"delegatedRoutingV1HttpApiClient": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/functions/_helia_delegated-routing-v1-http-api-client.delegatedRoutingV1HttpApiClient.html",
|
|
21
|
-
".:delegatedRoutingV1HttpApiClient": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/functions/_helia_delegated-routing-v1-http-api-client.delegatedRoutingV1HttpApiClient.html"
|
|
21
|
+
".:delegatedRoutingV1HttpApiClient": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/functions/_helia_delegated-routing-v1-http-api-client.delegatedRoutingV1HttpApiClient.html",
|
|
22
|
+
"delegatedRoutingV1HttpApiClientContentRouting": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/functions/_helia_delegated-routing-v1-http-api-client.delegatedRoutingV1HttpApiClientContentRouting.html",
|
|
23
|
+
".:delegatedRoutingV1HttpApiClientContentRouting": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/functions/_helia_delegated-routing-v1-http-api-client.delegatedRoutingV1HttpApiClientContentRouting.html",
|
|
24
|
+
"delegatedRoutingV1HttpApiClientPeerRouting": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/functions/_helia_delegated-routing-v1-http-api-client.delegatedRoutingV1HttpApiClientPeerRouting.html",
|
|
25
|
+
".:delegatedRoutingV1HttpApiClientPeerRouting": "https://ipfs.github.io/helia-delegated-routing-v1-http-api/functions/_helia_delegated-routing-v1-http-api-client.delegatedRoutingV1HttpApiClientPeerRouting.html"
|
|
22
26
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helia/delegated-routing-v1-http-api-client",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "A Delegated Routing V1 HTTP API client",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"homepage": "https://github.com/ipfs/helia-delegated-routing-v1-http-api/tree/main/packages/client#readme",
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
"exports": {
|
|
30
30
|
".": {
|
|
31
31
|
"types": "./dist/src/index.d.ts",
|
|
32
|
-
"import": "./dist/src/index.js"
|
|
32
|
+
"import": "./dist/src/index.js",
|
|
33
|
+
"module-sync": "./dist/src/index.js"
|
|
33
34
|
}
|
|
34
35
|
},
|
|
35
36
|
"release": {
|
|
@@ -144,20 +145,20 @@
|
|
|
144
145
|
"@multiformats/multiaddr": "^13.0.1",
|
|
145
146
|
"any-signal": "^4.1.1",
|
|
146
147
|
"browser-readablestream-to-it": "^2.0.9",
|
|
147
|
-
"ipns": "^10.0.2",
|
|
148
148
|
"it-first": "^3.0.8",
|
|
149
149
|
"it-map": "^3.1.3",
|
|
150
|
-
"it-ndjson": "^
|
|
151
|
-
"multiformats": "^
|
|
150
|
+
"it-ndjson": "^2.0.0",
|
|
151
|
+
"multiformats": "^14.0.0",
|
|
152
152
|
"p-defer": "^4.0.1",
|
|
153
153
|
"p-queue": "^9.0.0",
|
|
154
|
-
"uint8arrays": "^
|
|
154
|
+
"uint8arrays": "^6.1.1"
|
|
155
155
|
},
|
|
156
156
|
"devDependencies": {
|
|
157
157
|
"@libp2p/crypto": "^5.1.3",
|
|
158
158
|
"@libp2p/logger": "^6.0.5",
|
|
159
|
-
"aegir": "^
|
|
159
|
+
"aegir": "^48.0.4",
|
|
160
160
|
"body-parser": "^2.2.0",
|
|
161
|
+
"ipns": "^11.0.0",
|
|
161
162
|
"it-all": "^3.0.8",
|
|
162
163
|
"wherearewe": "^2.0.1"
|
|
163
164
|
},
|
package/src/client.ts
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
|
-
import { InvalidParametersError, NotFoundError,
|
|
1
|
+
import { InvalidParametersError, NotFoundError, setMaxListeners } from '@libp2p/interface'
|
|
2
2
|
import { peerIdFromString } from '@libp2p/peer-id'
|
|
3
3
|
import { multiaddr } from '@multiformats/multiaddr'
|
|
4
4
|
import { anySignal } from 'any-signal'
|
|
5
5
|
import toIt from 'browser-readablestream-to-it'
|
|
6
|
-
import { unmarshalIPNSRecord, marshalIPNSRecord, multihashToIPNSRoutingKey } from 'ipns'
|
|
7
|
-
import { ipnsValidator } from 'ipns/validator'
|
|
8
6
|
import { parse as ndjson } from 'it-ndjson'
|
|
9
7
|
import { CID } from 'multiformats/cid'
|
|
10
8
|
import defer from 'p-defer'
|
|
11
9
|
import PQueue from 'p-queue'
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import type { DelegatedRoutingV1HttpApiClient as DelegatedRoutingV1HttpApiClientInterface, DelegatedRoutingV1HttpApiClientInit, GetProvidersOptions, GetPeersOptions, GetIPNSOptions, PeerRecord, DelegatedRoutingV1HttpApiClientComponents, GetClosestPeersOptions } from './index.
|
|
15
|
-
import type {
|
|
10
|
+
import { withArrayBuffer } from 'uint8arrays/with-array-buffer'
|
|
11
|
+
import { BadResponseError, InvalidRequestError } from './errors.ts'
|
|
12
|
+
import type { DelegatedRoutingV1HttpApiClient as DelegatedRoutingV1HttpApiClientInterface, DelegatedRoutingV1HttpApiClientInit, GetProvidersOptions, GetPeersOptions, GetIPNSOptions, PeerRecord, DelegatedRoutingV1HttpApiClientComponents, GetClosestPeersOptions } from './index.ts'
|
|
13
|
+
import type { AbortOptions, Logger } from '@libp2p/interface'
|
|
16
14
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
17
|
-
import type { IPNSRecord } from 'ipns'
|
|
18
15
|
|
|
19
16
|
const defaultValues = {
|
|
20
17
|
concurrentRequests: 4,
|
|
@@ -29,8 +26,6 @@ export class DelegatedRoutingV1HttpApiClient implements DelegatedRoutingV1HttpAp
|
|
|
29
26
|
private readonly httpQueue: PQueue
|
|
30
27
|
private readonly shutDownController: AbortController
|
|
31
28
|
private readonly timeout: number
|
|
32
|
-
private readonly contentRouting: ContentRouting
|
|
33
|
-
private readonly peerRouting: PeerRouting
|
|
34
29
|
private readonly filterAddrs?: string[]
|
|
35
30
|
private readonly filterProtocols?: string[]
|
|
36
31
|
private readonly inFlightRequests: Map<string, Promise<Response>>
|
|
@@ -55,21 +50,11 @@ export class DelegatedRoutingV1HttpApiClient implements DelegatedRoutingV1HttpAp
|
|
|
55
50
|
this.timeout = init.timeout ?? defaultValues.timeout
|
|
56
51
|
this.filterAddrs = init.filterAddrs
|
|
57
52
|
this.filterProtocols = init.filterProtocols
|
|
58
|
-
this.contentRouting = new DelegatedRoutingV1HttpApiClientContentRouting(this)
|
|
59
|
-
this.peerRouting = new DelegatedRoutingV1HttpApiClientPeerRouting(this)
|
|
60
53
|
|
|
61
54
|
this.cacheName = init.cacheName ?? defaultValues.cacheName
|
|
62
55
|
this.cacheTTL = init.cacheTTL ?? defaultValues.cacheTTL
|
|
63
56
|
}
|
|
64
57
|
|
|
65
|
-
get [contentRoutingSymbol] (): ContentRouting {
|
|
66
|
-
return this.contentRouting
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
get [peerRoutingSymbol] (): PeerRouting {
|
|
70
|
-
return this.peerRouting
|
|
71
|
-
}
|
|
72
|
-
|
|
73
58
|
isStarted (): boolean {
|
|
74
59
|
return this.started
|
|
75
60
|
}
|
|
@@ -120,15 +105,14 @@ export class DelegatedRoutingV1HttpApiClient implements DelegatedRoutingV1HttpAp
|
|
|
120
105
|
|
|
121
106
|
// https://specs.ipfs.tech/routing/http-routing-v1/
|
|
122
107
|
const url = new URL(`${this.url}routing/v1/providers/${cid}`)
|
|
123
|
-
|
|
124
108
|
this.#addFilterParams(url, options.filterAddrs, options.filterProtocols)
|
|
125
|
-
|
|
109
|
+
|
|
110
|
+
const res = await this.#makeRequest(url.toString(), {
|
|
126
111
|
headers: {
|
|
127
112
|
accept: 'application/x-ndjson, application/json;q=0.8'
|
|
128
113
|
},
|
|
129
114
|
signal
|
|
130
|
-
}
|
|
131
|
-
const res = await this.#makeRequest(url.toString(), getOptions)
|
|
115
|
+
})
|
|
132
116
|
|
|
133
117
|
if (!res.ok) {
|
|
134
118
|
// Per IPIP-0513: Handle 404 as empty results (not an error)
|
|
@@ -194,8 +178,8 @@ export class DelegatedRoutingV1HttpApiClient implements DelegatedRoutingV1HttpAp
|
|
|
194
178
|
}
|
|
195
179
|
}
|
|
196
180
|
|
|
197
|
-
async * getPeers (
|
|
198
|
-
this.log('getPeers starts: %c',
|
|
181
|
+
async * getPeers (cid: CID, options: GetPeersOptions = {}): AsyncGenerator<PeerRecord> {
|
|
182
|
+
this.log('getPeers starts: %c', cid)
|
|
199
183
|
|
|
200
184
|
const timeoutSignal = AbortSignal.timeout(this.timeout)
|
|
201
185
|
const signal = anySignal([this.shutDownController.signal, timeoutSignal, options.signal])
|
|
@@ -212,11 +196,15 @@ export class DelegatedRoutingV1HttpApiClient implements DelegatedRoutingV1HttpAp
|
|
|
212
196
|
await onStart.promise
|
|
213
197
|
|
|
214
198
|
// https://specs.ipfs.tech/routing/http-routing-v1/
|
|
215
|
-
const url = new URL(`${this.url}routing/v1/peers/${
|
|
199
|
+
const url = new URL(`${this.url}routing/v1/peers/${cid}`)
|
|
216
200
|
this.#addFilterParams(url, options.filterAddrs, options.filterProtocols)
|
|
217
201
|
|
|
218
|
-
const
|
|
219
|
-
|
|
202
|
+
const res = await this.#makeRequest(url.toString(), {
|
|
203
|
+
headers: {
|
|
204
|
+
Accept: 'application/x-ndjson'
|
|
205
|
+
},
|
|
206
|
+
signal
|
|
207
|
+
})
|
|
220
208
|
|
|
221
209
|
// Per IPIP-0513: Handle 404 as empty results (not an error)
|
|
222
210
|
// Old servers return 404, new servers return 200 with empty array
|
|
@@ -260,19 +248,17 @@ export class DelegatedRoutingV1HttpApiClient implements DelegatedRoutingV1HttpAp
|
|
|
260
248
|
} finally {
|
|
261
249
|
signal.clear()
|
|
262
250
|
onFinish.resolve()
|
|
263
|
-
this.log('getPeers finished: %c',
|
|
251
|
+
this.log('getPeers finished: %c', cid)
|
|
264
252
|
}
|
|
265
253
|
}
|
|
266
254
|
|
|
267
|
-
async * getClosestPeers (key: CID
|
|
255
|
+
async * getClosestPeers (key: CID, options: GetClosestPeersOptions = {}): AsyncGenerator<PeerRecord> {
|
|
268
256
|
let target: string
|
|
269
257
|
|
|
270
|
-
if (
|
|
271
|
-
target = key.toCID().toString()
|
|
272
|
-
} else if (CID.asCID(key) === key || key instanceof CID) {
|
|
258
|
+
if (CID.asCID(key) === key || key instanceof CID) {
|
|
273
259
|
target = key.toV1().toString()
|
|
274
260
|
} else {
|
|
275
|
-
throw new InvalidParametersError('Key must be CID
|
|
261
|
+
throw new InvalidParametersError('Key must be CID')
|
|
276
262
|
}
|
|
277
263
|
|
|
278
264
|
this.log('getClosestPeers starts: %s', target)
|
|
@@ -295,8 +281,12 @@ export class DelegatedRoutingV1HttpApiClient implements DelegatedRoutingV1HttpAp
|
|
|
295
281
|
const url = new URL(`${this.url}routing/v1/dht/closest/peers/${target}`)
|
|
296
282
|
this.#addFilterParams(url, options.filterAddrs, options.filterProtocols)
|
|
297
283
|
|
|
298
|
-
const
|
|
299
|
-
|
|
284
|
+
const res = await this.#makeRequest(url.toString(), {
|
|
285
|
+
headers: {
|
|
286
|
+
Accept: 'application/x-ndjson'
|
|
287
|
+
},
|
|
288
|
+
signal
|
|
289
|
+
})
|
|
300
290
|
|
|
301
291
|
// Per IPIP-0513: Handle 404 as empty results (not an error)
|
|
302
292
|
// Old servers return 404, new servers return 200 with empty array
|
|
@@ -344,8 +334,8 @@ export class DelegatedRoutingV1HttpApiClient implements DelegatedRoutingV1HttpAp
|
|
|
344
334
|
}
|
|
345
335
|
}
|
|
346
336
|
|
|
347
|
-
async getIPNS (
|
|
348
|
-
this.log('getIPNS starts: %
|
|
337
|
+
async getIPNS (cid: CID, options: GetIPNSOptions = {}): Promise<Uint8Array<ArrayBuffer>> {
|
|
338
|
+
this.log('getIPNS starts: %c', cid)
|
|
349
339
|
|
|
350
340
|
const timeoutSignal = AbortSignal.timeout(this.timeout)
|
|
351
341
|
const signal = anySignal([this.shutDownController.signal, timeoutSignal, options.signal])
|
|
@@ -359,13 +349,17 @@ export class DelegatedRoutingV1HttpApiClient implements DelegatedRoutingV1HttpAp
|
|
|
359
349
|
})
|
|
360
350
|
|
|
361
351
|
// https://specs.ipfs.tech/routing/http-routing-v1/
|
|
362
|
-
const resource = `${this.url}routing/v1/ipns/${
|
|
352
|
+
const resource = `${this.url}routing/v1/ipns/${cid}`
|
|
363
353
|
|
|
364
354
|
try {
|
|
365
355
|
await onStart.promise
|
|
366
356
|
|
|
367
|
-
const
|
|
368
|
-
|
|
357
|
+
const res = await this.#makeRequest(resource, {
|
|
358
|
+
headers: {
|
|
359
|
+
Accept: 'application/vnd.ipfs.ipns-record'
|
|
360
|
+
},
|
|
361
|
+
signal
|
|
362
|
+
})
|
|
369
363
|
|
|
370
364
|
this.log('getIPNS GET %s %d', resource, res.status)
|
|
371
365
|
|
|
@@ -398,13 +392,8 @@ export class DelegatedRoutingV1HttpApiClient implements DelegatedRoutingV1HttpAp
|
|
|
398
392
|
}
|
|
399
393
|
|
|
400
394
|
const buf = await res.arrayBuffer()
|
|
401
|
-
const body = new Uint8Array(buf, 0, buf.byteLength)
|
|
402
395
|
|
|
403
|
-
|
|
404
|
-
await ipnsValidator(multihashToIPNSRoutingKey(libp2pKey.multihash), body)
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
return unmarshalIPNSRecord(body)
|
|
396
|
+
return new Uint8Array(buf, 0, buf.byteLength)
|
|
408
397
|
} catch (err: any) {
|
|
409
398
|
this.log.error('getIPNS GET %s error - %e', resource, err)
|
|
410
399
|
|
|
@@ -412,11 +401,11 @@ export class DelegatedRoutingV1HttpApiClient implements DelegatedRoutingV1HttpAp
|
|
|
412
401
|
} finally {
|
|
413
402
|
signal.clear()
|
|
414
403
|
onFinish.resolve()
|
|
415
|
-
this.log('getIPNS finished: %
|
|
404
|
+
this.log('getIPNS finished: %c', cid)
|
|
416
405
|
}
|
|
417
406
|
}
|
|
418
407
|
|
|
419
|
-
async putIPNS (libp2pKey: CID
|
|
408
|
+
async putIPNS (libp2pKey: CID, record: Uint8Array, options: AbortOptions = {}): Promise<void> {
|
|
420
409
|
this.log('putIPNS starts: %c', libp2pKey)
|
|
421
410
|
|
|
422
411
|
const timeoutSignal = AbortSignal.timeout(this.timeout)
|
|
@@ -436,10 +425,14 @@ export class DelegatedRoutingV1HttpApiClient implements DelegatedRoutingV1HttpAp
|
|
|
436
425
|
try {
|
|
437
426
|
await onStart.promise
|
|
438
427
|
|
|
439
|
-
const
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
428
|
+
const res = await this.#makeRequest(resource, {
|
|
429
|
+
method: 'PUT',
|
|
430
|
+
headers: {
|
|
431
|
+
'Content-Type': 'application/vnd.ipfs.ipns-record'
|
|
432
|
+
},
|
|
433
|
+
body: withArrayBuffer(record),
|
|
434
|
+
signal
|
|
435
|
+
})
|
|
443
436
|
|
|
444
437
|
this.log('putIPNS PUT %s %d', resource, res.status)
|
|
445
438
|
|
package/src/constants.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const CODE_LIBP2P_KEY = 0x72
|
package/src/index.ts
CHANGED
|
@@ -98,10 +98,10 @@
|
|
|
98
98
|
* ```
|
|
99
99
|
*/
|
|
100
100
|
|
|
101
|
-
import { DelegatedRoutingV1HttpApiClient as DelegatedRoutingV1HttpApiClientClass } from './client.
|
|
102
|
-
import
|
|
101
|
+
import { DelegatedRoutingV1HttpApiClient as DelegatedRoutingV1HttpApiClientClass } from './client.ts'
|
|
102
|
+
import { DelegatedRoutingV1HttpApiClientContentRouting, DelegatedRoutingV1HttpApiClientPeerRouting } from './routings.ts'
|
|
103
|
+
import type { AbortOptions, ComponentLogger, ContentRouting, PeerId, PeerRouting } from '@libp2p/interface'
|
|
103
104
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
104
|
-
import type { IPNSRecord } from 'ipns'
|
|
105
105
|
import type { CID } from 'multiformats/cid'
|
|
106
106
|
|
|
107
107
|
/**
|
|
@@ -179,16 +179,7 @@ export interface DelegatedRoutingV1HttpApiClientComponents {
|
|
|
179
179
|
logger: ComponentLogger
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
export
|
|
183
|
-
/**
|
|
184
|
-
* By default incoming IPNS records are validated, pass false here to skip
|
|
185
|
-
* validation and just return the record.
|
|
186
|
-
*
|
|
187
|
-
* @default true
|
|
188
|
-
*/
|
|
189
|
-
validate?: boolean
|
|
190
|
-
}
|
|
191
|
-
|
|
182
|
+
export type GetIPNSOptions = AbortOptions
|
|
192
183
|
export type GetProvidersOptions = FilterOptions & AbortOptions
|
|
193
184
|
export type GetPeersOptions = FilterOptions & AbortOptions
|
|
194
185
|
export type GetClosestPeersOptions = FilterOptions & AbortOptions
|
|
@@ -207,25 +198,25 @@ export interface DelegatedRoutingV1HttpApiClient {
|
|
|
207
198
|
|
|
208
199
|
/**
|
|
209
200
|
* Returns an async generator of {@link PeerRecord}s for the provided
|
|
210
|
-
* {@link
|
|
201
|
+
* {@link CID}
|
|
211
202
|
*/
|
|
212
|
-
getPeers(
|
|
203
|
+
getPeers(cid: CID, options?: GetPeersOptions): AsyncGenerator<PeerRecord>
|
|
213
204
|
|
|
214
205
|
/**
|
|
215
206
|
* Returns an async generator of {@link PeerRecord}s of the closest peers to
|
|
216
207
|
* the supplied key
|
|
217
208
|
*/
|
|
218
|
-
getClosestPeers (
|
|
209
|
+
getClosestPeers (cid: CID, options?: GetClosestPeersOptions): AsyncGenerator<PeerRecord>
|
|
219
210
|
|
|
220
211
|
/**
|
|
221
|
-
* Returns a promise of a
|
|
212
|
+
* Returns a promise of a serialized IPNS record for passed CID
|
|
222
213
|
*/
|
|
223
|
-
getIPNS(
|
|
214
|
+
getIPNS(cid: CID, options?: GetIPNSOptions): Promise<Uint8Array<ArrayBuffer>>
|
|
224
215
|
|
|
225
216
|
/**
|
|
226
|
-
* Publishes
|
|
217
|
+
* Publishes a serialized IPNS record for the passed CID
|
|
227
218
|
*/
|
|
228
|
-
putIPNS(
|
|
219
|
+
putIPNS(cid: CID, record: Uint8Array, options?: AbortOptions): Promise<void>
|
|
229
220
|
|
|
230
221
|
/**
|
|
231
222
|
* Create the request/response cache used to ensure duplicate requests aren't
|
|
@@ -246,3 +237,11 @@ export interface DelegatedRoutingV1HttpApiClient {
|
|
|
246
237
|
export function delegatedRoutingV1HttpApiClient (init: DelegatedRoutingV1HttpApiClientInit): (components: DelegatedRoutingV1HttpApiClientComponents) => DelegatedRoutingV1HttpApiClient {
|
|
247
238
|
return (components) => new DelegatedRoutingV1HttpApiClientClass(components, init)
|
|
248
239
|
}
|
|
240
|
+
|
|
241
|
+
export function delegatedRoutingV1HttpApiClientContentRouting (init: DelegatedRoutingV1HttpApiClientInit): (components: DelegatedRoutingV1HttpApiClientComponents) => ContentRouting {
|
|
242
|
+
return (components) => new DelegatedRoutingV1HttpApiClientContentRouting(delegatedRoutingV1HttpApiClient(init)(components))
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export function delegatedRoutingV1HttpApiClientPeerRouting (init: DelegatedRoutingV1HttpApiClientInit): (components: DelegatedRoutingV1HttpApiClientComponents) => PeerRouting {
|
|
246
|
+
return (components) => new DelegatedRoutingV1HttpApiClientPeerRouting(delegatedRoutingV1HttpApiClient(init)(components))
|
|
247
|
+
}
|
package/src/routings.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { NotFoundError } from '@libp2p/interface'
|
|
2
|
-
import { peerIdFromMultihash } from '@libp2p/peer-id'
|
|
3
|
-
import { marshalIPNSRecord, multihashFromIPNSRoutingKey, unmarshalIPNSRecord } from 'ipns'
|
|
1
|
+
import { contentRoutingSymbol, NotFoundError, peerRoutingSymbol } from '@libp2p/interface'
|
|
4
2
|
import first from 'it-first'
|
|
5
3
|
import map from 'it-map'
|
|
6
4
|
import { digest } from 'multiformats'
|
|
7
5
|
import { CID } from 'multiformats/cid'
|
|
6
|
+
import * as raw from 'multiformats/codecs/raw'
|
|
7
|
+
import * as Digest from 'multiformats/hashes/digest'
|
|
8
|
+
import { identity } from 'multiformats/hashes/identity'
|
|
8
9
|
import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
|
|
9
10
|
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
|
|
10
|
-
import type { DelegatedRoutingV1HttpApiClient } from './index.
|
|
11
|
-
import type { ContentRouting, PeerRouting, AbortOptions, PeerId, PeerInfo, Provider } from '@libp2p/interface'
|
|
11
|
+
import type { DelegatedRoutingV1HttpApiClient } from './index.ts'
|
|
12
|
+
import type { ContentRouting, PeerRouting, AbortOptions, PeerId, PeerInfo, Provider, Startable } from '@libp2p/interface'
|
|
12
13
|
|
|
13
14
|
const IPNS_PREFIX = uint8ArrayFromString('/ipns/')
|
|
14
15
|
|
|
@@ -19,13 +20,25 @@ function isIPNSKey (key: Uint8Array): boolean {
|
|
|
19
20
|
/**
|
|
20
21
|
* Wrapper class to convert [http-routing-v1 content events](https://specs.ipfs.tech/routing/http-routing-v1/#response-body) into returned values
|
|
21
22
|
*/
|
|
22
|
-
export class DelegatedRoutingV1HttpApiClientContentRouting implements ContentRouting {
|
|
23
|
+
export class DelegatedRoutingV1HttpApiClientContentRouting implements ContentRouting, Startable {
|
|
23
24
|
private readonly client: DelegatedRoutingV1HttpApiClient
|
|
24
25
|
|
|
25
26
|
constructor (client: DelegatedRoutingV1HttpApiClient) {
|
|
26
27
|
this.client = client
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
get [contentRoutingSymbol] (): ContentRouting {
|
|
31
|
+
return this
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async start (): Promise<void> {
|
|
35
|
+
await this.client.start()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async stop (): Promise<void> {
|
|
39
|
+
await this.client.stop()
|
|
40
|
+
}
|
|
41
|
+
|
|
29
42
|
async * findProviders (cid: CID, options: AbortOptions = {}): AsyncIterable<Provider> {
|
|
30
43
|
try {
|
|
31
44
|
yield * map(this.client.getProviders(cid, options), (record) => {
|
|
@@ -59,11 +72,10 @@ export class DelegatedRoutingV1HttpApiClientContentRouting implements ContentRou
|
|
|
59
72
|
return
|
|
60
73
|
}
|
|
61
74
|
|
|
62
|
-
const digest =
|
|
75
|
+
const digest = Digest.decode(key.slice(IPNS_PREFIX.length))
|
|
63
76
|
const cid = CID.createV1(0x72, digest)
|
|
64
|
-
const record = unmarshalIPNSRecord(value)
|
|
65
77
|
|
|
66
|
-
await this.client.putIPNS(cid,
|
|
78
|
+
await this.client.putIPNS(cid, value, options)
|
|
67
79
|
}
|
|
68
80
|
|
|
69
81
|
async get (key: Uint8Array, options?: AbortOptions): Promise<Uint8Array> {
|
|
@@ -71,13 +83,11 @@ export class DelegatedRoutingV1HttpApiClientContentRouting implements ContentRou
|
|
|
71
83
|
throw new NotFoundError('Not found')
|
|
72
84
|
}
|
|
73
85
|
|
|
74
|
-
const digest =
|
|
86
|
+
const digest = Digest.decode(key.slice(IPNS_PREFIX.length))
|
|
75
87
|
const cid = CID.createV1(0x72, digest)
|
|
76
88
|
|
|
77
89
|
try {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return marshalIPNSRecord(record)
|
|
90
|
+
return await this.client.getIPNS(cid, options)
|
|
81
91
|
} catch (err: any) {
|
|
82
92
|
// BadResponseError is thrown when the response had no body, which means
|
|
83
93
|
// the record couldn't be found
|
|
@@ -97,15 +107,27 @@ export class DelegatedRoutingV1HttpApiClientContentRouting implements ContentRou
|
|
|
97
107
|
/**
|
|
98
108
|
* Wrapper class to convert [http-routing-v1](https://specs.ipfs.tech/routing/http-routing-v1/#response-body-0) events into expected libp2p values
|
|
99
109
|
*/
|
|
100
|
-
export class DelegatedRoutingV1HttpApiClientPeerRouting implements PeerRouting {
|
|
110
|
+
export class DelegatedRoutingV1HttpApiClientPeerRouting implements PeerRouting, Startable {
|
|
101
111
|
private readonly client: DelegatedRoutingV1HttpApiClient
|
|
102
112
|
|
|
103
113
|
constructor (client: DelegatedRoutingV1HttpApiClient) {
|
|
104
114
|
this.client = client
|
|
105
115
|
}
|
|
106
116
|
|
|
117
|
+
get [peerRoutingSymbol] (): PeerRouting {
|
|
118
|
+
return this
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async start (): Promise<void> {
|
|
122
|
+
await this.client.start()
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async stop (): Promise<void> {
|
|
126
|
+
await this.client.stop()
|
|
127
|
+
}
|
|
128
|
+
|
|
107
129
|
async findPeer (peerId: PeerId, options: AbortOptions = {}): Promise<PeerInfo> {
|
|
108
|
-
const peer = await first(this.client.getPeers(peerId, options))
|
|
130
|
+
const peer = await first(this.client.getPeers(peerId.toCID(), options))
|
|
109
131
|
|
|
110
132
|
if (peer != null) {
|
|
111
133
|
return {
|
|
@@ -118,15 +140,19 @@ export class DelegatedRoutingV1HttpApiClientPeerRouting implements PeerRouting {
|
|
|
118
140
|
}
|
|
119
141
|
|
|
120
142
|
async * getClosestPeers (key: Uint8Array, options: AbortOptions = {}): AsyncIterable<PeerInfo> {
|
|
121
|
-
let
|
|
143
|
+
let cid: CID
|
|
122
144
|
|
|
123
145
|
try {
|
|
124
|
-
|
|
146
|
+
cid = CID.decode(key)
|
|
125
147
|
} catch {
|
|
126
|
-
|
|
148
|
+
try {
|
|
149
|
+
cid = CID.createV1(0x72, digest.decode(key))
|
|
150
|
+
} catch {
|
|
151
|
+
cid = CID.createV1(raw.code, identity.digest(key))
|
|
152
|
+
}
|
|
127
153
|
}
|
|
128
154
|
|
|
129
|
-
for await (const peer of this.client.getClosestPeers(
|
|
155
|
+
for await (const peer of this.client.getClosestPeers(cid, options)) {
|
|
130
156
|
yield {
|
|
131
157
|
id: peer.ID,
|
|
132
158
|
multiaddrs: peer.Addrs ?? []
|