@helia/delegated-routing-client 0.0.0-1361bfa5

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.
@@ -0,0 +1,18 @@
1
+ import { CID } from 'multiformats/cid';
2
+ import type { DelegatedRoutingV1HttpApiClientComponents, DelegatedRoutingV1HttpApiClientInit } from '@helia/delegated-routing-v1-http-api-client';
3
+ import type { Peer, Provider, Router, RoutingOptions } from '@helia/interface';
4
+ import type { Version } from 'multiformats';
5
+ export declare class DelegatedHTTPRouter implements Router {
6
+ readonly name = "delegated-http-router";
7
+ private readonly client;
8
+ constructor(components: DelegatedRoutingV1HttpApiClientComponents, init: DelegatedRoutingV1HttpApiClientInit);
9
+ provide(cid: CID, options?: RoutingOptions): Promise<void>;
10
+ cancelReprovide(cid?: CID, options?: RoutingOptions): Promise<void>;
11
+ findProviders(cid: CID<unknown, number, number, Version>, options?: RoutingOptions): AsyncIterable<Provider>;
12
+ put(key: Uint8Array, value: Uint8Array, options?: RoutingOptions): Promise<void>;
13
+ get(key: Uint8Array, options?: RoutingOptions): Promise<Uint8Array>;
14
+ findPeer(peerId: CID, options?: RoutingOptions): Promise<Peer>;
15
+ getClosestPeers(key: Uint8Array, options?: RoutingOptions): AsyncIterable<Peer>;
16
+ toString(): string;
17
+ }
18
+ //# sourceMappingURL=delegated-routing-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegated-routing-router.d.ts","sourceRoot":"","sources":["../../src/delegated-routing-router.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAItC,OAAO,KAAK,EAAmC,yCAAyC,EAAE,mCAAmC,EAAE,MAAM,6CAA6C,CAAA;AAClL,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC9E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAQ3C,qBAAa,mBAAoB,YAAW,MAAM;IAChD,SAAgB,IAAI,2BAA0B;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;gBAE3C,UAAU,EAAE,yCAAyC,EAAE,IAAI,EAAE,mCAAmC;IAIvG,OAAO,CAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D,eAAe,CAAE,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlE,aAAa,CAAE,GAAG,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,aAAa,CAAC,QAAQ,CAAC;IAW/G,GAAG,CAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjF,GAAG,CAAE,GAAG,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IAqBpE,QAAQ,CAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAa7D,eAAe,CAAE,GAAG,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,aAAa,CAAC,IAAI,CAAC;IAIxF,QAAQ,IAAK,MAAM;CAGpB"}
@@ -0,0 +1,78 @@
1
+ import { delegatedRoutingV1HttpApiClient } from '@helia/delegated-routing-v1-http-api-client';
2
+ import { NotFoundError } from '@libp2p/interface';
3
+ import first from 'it-first';
4
+ import map from 'it-map';
5
+ import { CID } from 'multiformats/cid';
6
+ import * as Digest from 'multiformats/hashes/digest';
7
+ import { equals as uint8ArrayEquals } from 'uint8arrays/equals';
8
+ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
9
+ const IPNS_PREFIX = uint8ArrayFromString('/ipns/');
10
+ function isIPNSKey(key) {
11
+ return uint8ArrayEquals(key.subarray(0, IPNS_PREFIX.byteLength), IPNS_PREFIX);
12
+ }
13
+ export class DelegatedHTTPRouter {
14
+ name = 'delegated-http-router';
15
+ client;
16
+ constructor(components, init) {
17
+ this.client = delegatedRoutingV1HttpApiClient(init)(components);
18
+ }
19
+ async provide(cid, options) {
20
+ // noop
21
+ }
22
+ async cancelReprovide(cid, options) {
23
+ // noop
24
+ }
25
+ async *findProviders(cid, options) {
26
+ yield* map(this.client.getProviders(cid, options), (record) => {
27
+ return {
28
+ id: record.ID,
29
+ multiaddrs: record.Addrs,
30
+ protocols: record.Protocols,
31
+ routing: 'delegated-http-routing'
32
+ };
33
+ });
34
+ }
35
+ async put(key, value, options) {
36
+ if (!isIPNSKey(key)) {
37
+ return;
38
+ }
39
+ const digest = Digest.decode(key.slice(IPNS_PREFIX.length));
40
+ const cid = CID.createV1(0x72, digest);
41
+ await this.client.putIPNS(cid, value, options);
42
+ }
43
+ async get(key, options) {
44
+ if (!isIPNSKey(key)) {
45
+ throw new NotFoundError('Not found');
46
+ }
47
+ const digest = Digest.decode(key.slice(IPNS_PREFIX.length));
48
+ const cid = CID.createV1(0x72, digest);
49
+ try {
50
+ return await this.client.getIPNS(cid, options);
51
+ }
52
+ catch (err) {
53
+ // BadResponseError is thrown when the response had no body, which means
54
+ // the record couldn't be found
55
+ if (err.name === 'BadResponseError') {
56
+ throw new NotFoundError('Not found');
57
+ }
58
+ throw err;
59
+ }
60
+ }
61
+ async findPeer(peerId, options) {
62
+ const peer = await first(this.client.getPeers(peerId, options));
63
+ if (peer != null) {
64
+ return {
65
+ id: peer.ID,
66
+ multiaddrs: peer.Addrs ?? []
67
+ };
68
+ }
69
+ throw new NotFoundError('Not found');
70
+ }
71
+ async *getClosestPeers(key, options) {
72
+ // noop
73
+ }
74
+ toString() {
75
+ return `DelegatedHTTPRouter(${this.client.url})`;
76
+ }
77
+ }
78
+ //# sourceMappingURL=delegated-routing-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegated-routing-router.js","sourceRoot":"","sources":["../../src/delegated-routing-router.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { delegatedHTTPRoutingDefaults } from './utils/delegated-http-routing-defaults.ts';
2
+ import type { DelegatedRoutingV1HttpApiClientInit } from '@helia/delegated-routing-v1-http-api-client';
3
+ import type { Router } from '@helia/interface';
4
+ export { delegatedHTTPRoutingDefaults };
5
+ export type { DelegatedRoutingV1HttpApiClientInit };
6
+ /**
7
+ * Creates a Helia Router that connects to an endpoint that supports the [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) spec.
8
+ */
9
+ export declare function delegatedHTTPRouter(init: DelegatedRoutingV1HttpApiClientInit): (components: any) => Router;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,4CAA4C,CAAA;AACzF,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,6CAA6C,CAAA;AACtG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,EAAE,4BAA4B,EAAE,CAAA;AACvC,YAAY,EAAE,mCAAmC,EAAE,CAAA;AAEnD;;GAEG;AACH,wBAAgB,mBAAmB,CAAE,IAAI,EAAE,mCAAmC,GAAG,CAAC,UAAU,EAAE,GAAG,KAAK,MAAM,CAE3G"}
@@ -0,0 +1,10 @@
1
+ import { DelegatedHTTPRouter } from "./delegated-routing-router.js";
2
+ import { delegatedHTTPRoutingDefaults } from "./utils/delegated-http-routing-defaults.js";
3
+ export { delegatedHTTPRoutingDefaults };
4
+ /**
5
+ * Creates a Helia Router that connects to an endpoint that supports the [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) spec.
6
+ */
7
+ export function delegatedHTTPRouter(init) {
8
+ return (components) => new DelegatedHTTPRouter(components, delegatedHTTPRoutingDefaults(init));
9
+ }
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAA;AACnE,OAAO,EAAE,4BAA4B,EAAE,MAAM,4CAA4C,CAAA;AAIzF,OAAO,EAAE,4BAA4B,EAAE,CAAA;AAGvC;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAE,IAAyC;IAC5E,OAAO,CAAC,UAAe,EAAE,EAAE,CAAC,IAAI,mBAAmB,CAAC,UAAU,EAAE,4BAA4B,CAAC,IAAI,CAAC,CAAC,CAAA;AACrG,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { DelegatedRoutingV1HttpApiClientInit } from '@helia/delegated-routing-v1-http-api-client';
2
+ export declare function delegatedHTTPRoutingDefaults(init?: DelegatedRoutingV1HttpApiClientInit): DelegatedRoutingV1HttpApiClientInit;
3
+ //# sourceMappingURL=delegated-http-routing-defaults.browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegated-http-routing-defaults.browser.d.ts","sourceRoot":"","sources":["../../../src/utils/delegated-http-routing-defaults.browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,6CAA6C,CAAA;AAEtG,wBAAgB,4BAA4B,CAAE,IAAI,CAAC,EAAE,mCAAmC,GAAG,mCAAmC,CAM7H"}
@@ -0,0 +1,8 @@
1
+ export function delegatedHTTPRoutingDefaults(init) {
2
+ return {
3
+ url: 'https://delegated-ipfs.dev',
4
+ filterProtocols: ['unknown', 'transport-bitswap', 'transport-ipfs-gateway-http'],
5
+ filterAddrs: ['https', 'webtransport', 'webrtc', 'webrtc-direct', 'wss', 'tls']
6
+ };
7
+ }
8
+ //# sourceMappingURL=delegated-http-routing-defaults.browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegated-http-routing-defaults.browser.js","sourceRoot":"","sources":["../../../src/utils/delegated-http-routing-defaults.browser.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,4BAA4B,CAAE,IAA0C;IACtF,OAAO;QACL,GAAG,EAAE,4BAA4B;QACjC,eAAe,EAAE,CAAC,SAAS,EAAE,mBAAmB,EAAE,6BAA6B,CAAC;QAChF,WAAW,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC;KAChF,CAAA;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { DelegatedRoutingV1HttpApiClientInit } from '@helia/delegated-routing-v1-http-api-client';
2
+ export declare function delegatedHTTPRoutingDefaults(init?: DelegatedRoutingV1HttpApiClientInit): DelegatedRoutingV1HttpApiClientInit;
3
+ //# sourceMappingURL=delegated-http-routing-defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegated-http-routing-defaults.d.ts","sourceRoot":"","sources":["../../../src/utils/delegated-http-routing-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,6CAA6C,CAAA;AAEtG,wBAAgB,4BAA4B,CAAE,IAAI,CAAC,EAAE,mCAAmC,GAAG,mCAAmC,CAO7H"}
@@ -0,0 +1,9 @@
1
+ export function delegatedHTTPRoutingDefaults(init) {
2
+ return {
3
+ url: 'https://delegated-ipfs.dev',
4
+ filterProtocols: ['unknown', 'transport-bitswap', 'transport-ipfs-gateway-http'],
5
+ filterAddrs: ['https', 'tcp', 'webrtc', 'webrtc-direct', 'wss', 'tls'],
6
+ ...(init ?? {})
7
+ };
8
+ }
9
+ //# sourceMappingURL=delegated-http-routing-defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegated-http-routing-defaults.js","sourceRoot":"","sources":["../../../src/utils/delegated-http-routing-defaults.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,4BAA4B,CAAE,IAA0C;IACtF,OAAO;QACL,GAAG,EAAE,4BAA4B;QACjC,eAAe,EAAE,CAAC,SAAS,EAAE,mBAAmB,EAAE,6BAA6B,CAAC;QAChF,WAAW,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC;QACtE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;KAChB,CAAA;AACH,CAAC"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@helia/delegated-routing-client",
3
+ "version": "0.0.0-1361bfa5",
4
+ "description": "Use HTTP Delegated Routers with Helia",
5
+ "license": "Apache-2.0 OR MIT",
6
+ "homepage": "https://github.com/ipfs/helia/tree/main/packages/delegated-routing-client#readme",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/ipfs/helia.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/ipfs/helia/issues"
13
+ },
14
+ "publishConfig": {
15
+ "access": "public",
16
+ "provenance": true
17
+ },
18
+ "keywords": [
19
+ "IPFS"
20
+ ],
21
+ "type": "module",
22
+ "types": "./dist/src/index.d.ts",
23
+ "files": [
24
+ "src",
25
+ "dist",
26
+ "!dist/test",
27
+ "!**/*.tsbuildinfo"
28
+ ],
29
+ "exports": {
30
+ ".": {
31
+ "types": "./dist/src/index.d.ts",
32
+ "import": "./dist/src/index.js",
33
+ "module-sync": "./dist/src/index.js"
34
+ }
35
+ },
36
+ "scripts": {
37
+ "clean": "aegir clean",
38
+ "lint": "aegir lint",
39
+ "dep-check": "aegir dep-check",
40
+ "doc-check": "aegir doc-check",
41
+ "build": "aegir build",
42
+ "test": "aegir test",
43
+ "test:chrome": "aegir test -t browser --cov",
44
+ "test:chrome-webworker": "aegir test -t webworker",
45
+ "test:firefox": "aegir test -t browser -- --browser firefox",
46
+ "test:firefox-webworker": "aegir test -t webworker -- --browser firefox",
47
+ "test:node": "aegir test -t node --cov",
48
+ "test:electron-main": "aegir test -t electron-main"
49
+ },
50
+ "dependencies": {
51
+ "@helia/delegated-routing-v1-http-api-client": "^8.0.0",
52
+ "@helia/interface": "6.2.1-1361bfa5",
53
+ "@libp2p/interface": "^3.2.3",
54
+ "it-first": "^3.0.11",
55
+ "it-map": "^3.1.6",
56
+ "multiformats": "^14.0.0",
57
+ "uint8arrays": "^6.1.1"
58
+ },
59
+ "devDependencies": {
60
+ "@libp2p/logger": "^6.2.8",
61
+ "@libp2p/peer-id": "^6.0.10",
62
+ "aegir": "^48.0.11",
63
+ "it-drain": "^3.0.12",
64
+ "sinon-ts": "^2.0.0"
65
+ },
66
+ "browser": {
67
+ "./dist/src/utils/delegated-http-routing-defaults.js": "./dist/src/utils/delegated-http-routing-defaults.browser.js"
68
+ },
69
+ "sideEffects": false
70
+ }
@@ -0,0 +1,98 @@
1
+ import { delegatedRoutingV1HttpApiClient } from '@helia/delegated-routing-v1-http-api-client'
2
+ import { NotFoundError } from '@libp2p/interface'
3
+ import first from 'it-first'
4
+ import map from 'it-map'
5
+ import { CID } from 'multiformats/cid'
6
+ import * as Digest from 'multiformats/hashes/digest'
7
+ import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
8
+ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
9
+ import type { DelegatedRoutingV1HttpApiClient, DelegatedRoutingV1HttpApiClientComponents, DelegatedRoutingV1HttpApiClientInit } from '@helia/delegated-routing-v1-http-api-client'
10
+ import type { Peer, Provider, Router, RoutingOptions } from '@helia/interface'
11
+ import type { Version } from 'multiformats'
12
+
13
+ const IPNS_PREFIX = uint8ArrayFromString('/ipns/')
14
+
15
+ function isIPNSKey (key: Uint8Array): boolean {
16
+ return uint8ArrayEquals(key.subarray(0, IPNS_PREFIX.byteLength), IPNS_PREFIX)
17
+ }
18
+
19
+ export class DelegatedHTTPRouter implements Router {
20
+ public readonly name = 'delegated-http-router'
21
+ private readonly client: DelegatedRoutingV1HttpApiClient
22
+
23
+ constructor (components: DelegatedRoutingV1HttpApiClientComponents, init: DelegatedRoutingV1HttpApiClientInit) {
24
+ this.client = delegatedRoutingV1HttpApiClient(init)(components)
25
+ }
26
+
27
+ async provide (cid: CID, options?: RoutingOptions): Promise<void> {
28
+ // noop
29
+ }
30
+
31
+ async cancelReprovide (cid?: CID, options?: RoutingOptions): Promise<void> {
32
+ // noop
33
+ }
34
+
35
+ async * findProviders (cid: CID<unknown, number, number, Version>, options?: RoutingOptions): AsyncIterable<Provider> {
36
+ yield * map(this.client.getProviders(cid, options), (record) => {
37
+ return {
38
+ id: record.ID,
39
+ multiaddrs: record.Addrs,
40
+ protocols: record.Protocols,
41
+ routing: 'delegated-http-routing'
42
+ }
43
+ })
44
+ }
45
+
46
+ async put (key: Uint8Array, value: Uint8Array, options?: RoutingOptions): Promise<void> {
47
+ if (!isIPNSKey(key)) {
48
+ return
49
+ }
50
+
51
+ const digest = Digest.decode(key.slice(IPNS_PREFIX.length))
52
+ const cid = CID.createV1(0x72, digest)
53
+
54
+ await this.client.putIPNS(cid, value, options)
55
+ }
56
+
57
+ async get (key: Uint8Array, options?: RoutingOptions): Promise<Uint8Array> {
58
+ if (!isIPNSKey(key)) {
59
+ throw new NotFoundError('Not found')
60
+ }
61
+
62
+ const digest = Digest.decode(key.slice(IPNS_PREFIX.length))
63
+ const cid = CID.createV1(0x72, digest)
64
+
65
+ try {
66
+ return await this.client.getIPNS(cid, options)
67
+ } catch (err: any) {
68
+ // BadResponseError is thrown when the response had no body, which means
69
+ // the record couldn't be found
70
+ if (err.name === 'BadResponseError') {
71
+ throw new NotFoundError('Not found')
72
+ }
73
+
74
+ throw err
75
+ }
76
+ }
77
+
78
+ async findPeer (peerId: CID, options?: RoutingOptions): Promise<Peer> {
79
+ const peer = await first(this.client.getPeers(peerId, options))
80
+
81
+ if (peer != null) {
82
+ return {
83
+ id: peer.ID,
84
+ multiaddrs: peer.Addrs ?? []
85
+ }
86
+ }
87
+
88
+ throw new NotFoundError('Not found')
89
+ }
90
+
91
+ async * getClosestPeers (key: Uint8Array, options?: RoutingOptions): AsyncIterable<Peer> {
92
+ // noop
93
+ }
94
+
95
+ toString (): string {
96
+ return `DelegatedHTTPRouter(${this.client.url})`
97
+ }
98
+ }
package/src/index.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { DelegatedHTTPRouter } from './delegated-routing-router.ts'
2
+ import { delegatedHTTPRoutingDefaults } from './utils/delegated-http-routing-defaults.ts'
3
+ import type { DelegatedRoutingV1HttpApiClientInit } from '@helia/delegated-routing-v1-http-api-client'
4
+ import type { Router } from '@helia/interface'
5
+
6
+ export { delegatedHTTPRoutingDefaults }
7
+ export type { DelegatedRoutingV1HttpApiClientInit }
8
+
9
+ /**
10
+ * Creates a Helia Router that connects to an endpoint that supports the [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) spec.
11
+ */
12
+ export function delegatedHTTPRouter (init: DelegatedRoutingV1HttpApiClientInit): (components: any) => Router {
13
+ return (components: any) => new DelegatedHTTPRouter(components, delegatedHTTPRoutingDefaults(init))
14
+ }
@@ -0,0 +1,9 @@
1
+ import type { DelegatedRoutingV1HttpApiClientInit } from '@helia/delegated-routing-v1-http-api-client'
2
+
3
+ export function delegatedHTTPRoutingDefaults (init?: DelegatedRoutingV1HttpApiClientInit): DelegatedRoutingV1HttpApiClientInit {
4
+ return {
5
+ url: 'https://delegated-ipfs.dev',
6
+ filterProtocols: ['unknown', 'transport-bitswap', 'transport-ipfs-gateway-http'],
7
+ filterAddrs: ['https', 'webtransport', 'webrtc', 'webrtc-direct', 'wss', 'tls']
8
+ }
9
+ }
@@ -0,0 +1,10 @@
1
+ import type { DelegatedRoutingV1HttpApiClientInit } from '@helia/delegated-routing-v1-http-api-client'
2
+
3
+ export function delegatedHTTPRoutingDefaults (init?: DelegatedRoutingV1HttpApiClientInit): DelegatedRoutingV1HttpApiClientInit {
4
+ return {
5
+ url: 'https://delegated-ipfs.dev',
6
+ filterProtocols: ['unknown', 'transport-bitswap', 'transport-ipfs-gateway-http'],
7
+ filterAddrs: ['https', 'tcp', 'webrtc', 'webrtc-direct', 'wss', 'tls'],
8
+ ...(init ?? {})
9
+ }
10
+ }