helia-coord 1.9.7 → 2.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/examples/create-helia-node.js +25 -3
- package/examples/start-node.js +9 -1
- package/lib/create-helia-node.js +263 -0
- package/package.json +32 -19
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
// Global npm libraries
|
|
8
8
|
import { createHelia } from 'helia'
|
|
9
|
+
import { libp2pRouting } from '@helia/routers'
|
|
10
|
+
import { bitswap } from '@helia/block-brokers'
|
|
9
11
|
import fs from 'fs'
|
|
10
12
|
import { FsBlockstore } from 'blockstore-fs'
|
|
11
13
|
import { FsDatastore } from 'datastore-fs'
|
|
@@ -13,9 +15,10 @@ import { createLibp2p } from 'libp2p'
|
|
|
13
15
|
import { tcp } from '@libp2p/tcp'
|
|
14
16
|
import { noise } from '@chainsafe/libp2p-noise'
|
|
15
17
|
import { yamux } from '@chainsafe/libp2p-yamux'
|
|
16
|
-
|
|
18
|
+
import { bootstrap } from '@libp2p/bootstrap'
|
|
17
19
|
// import { identifyService } from 'libp2p/identify'
|
|
18
20
|
import { identify } from '@libp2p/identify'
|
|
21
|
+
import { kadDHT } from '@libp2p/kad-dht'
|
|
19
22
|
// import { circuitRelayTransport } from 'libp2p/circuit-relay'
|
|
20
23
|
import { circuitRelayTransport } from '@libp2p/circuit-relay-v2'
|
|
21
24
|
import { gossipsub } from '@chainsafe/libp2p-gossipsub'
|
|
@@ -81,7 +84,11 @@ class CreateHeliaNode {
|
|
|
81
84
|
// Configure services
|
|
82
85
|
const services = {
|
|
83
86
|
identify: identify(),
|
|
84
|
-
pubsub: gossipsub({ allowPublishToZeroTopicPeers: true })
|
|
87
|
+
pubsub: gossipsub({ allowPublishToZeroTopicPeers: true }),
|
|
88
|
+
dht: kadDHT({
|
|
89
|
+
protocol: '/psf/kad/1.0.0',
|
|
90
|
+
clientMode: false
|
|
91
|
+
})
|
|
85
92
|
}
|
|
86
93
|
|
|
87
94
|
// libp2p is the networking layer that underpins Helia
|
|
@@ -108,6 +115,15 @@ class CreateHeliaNode {
|
|
|
108
115
|
streamMuxers: [
|
|
109
116
|
yamux()
|
|
110
117
|
],
|
|
118
|
+
peerDiscovery: [
|
|
119
|
+
bootstrap({
|
|
120
|
+
list: [
|
|
121
|
+
'/ip4/78.46.129.7/tcp/4001/p2p/12D3KooWEBzgK8a5TpMfLotuj7jJnEK41gbD9LZK6qCpxNrX43E9',
|
|
122
|
+
'/ip4/5.78.70.29/tcp/4001/p2p/12D3KooWSREJ6x2DJSYrA1xRD2Qs6D4DHncsHmNnTHuMKHnqpG2i',
|
|
123
|
+
'/ip4/143.198.134.59/tcp/4101/p2p/12D3KooWHogx3RcyNiSuY6SzS8GxzTAqtDCYzy17yQ1StWaLvX9j'
|
|
124
|
+
]
|
|
125
|
+
})
|
|
126
|
+
],
|
|
111
127
|
services
|
|
112
128
|
})
|
|
113
129
|
|
|
@@ -115,7 +131,13 @@ class CreateHeliaNode {
|
|
|
115
131
|
const helia = await createHelia({
|
|
116
132
|
blockstore,
|
|
117
133
|
datastore,
|
|
118
|
-
libp2p
|
|
134
|
+
libp2p,
|
|
135
|
+
routers: [
|
|
136
|
+
libp2pRouting(libp2p)
|
|
137
|
+
],
|
|
138
|
+
blockBrokers: [
|
|
139
|
+
bitswap()
|
|
140
|
+
]
|
|
119
141
|
})
|
|
120
142
|
|
|
121
143
|
return helia
|
package/examples/start-node.js
CHANGED
|
@@ -10,6 +10,14 @@ import SlpWallet from 'minimal-slp-wallet'
|
|
|
10
10
|
import IpfsCoord from '../index.js'
|
|
11
11
|
import CreateHeliaNode from './create-helia-node.js'
|
|
12
12
|
|
|
13
|
+
// Catch uncaught errors from libp2p internals to prevent crashes.
|
|
14
|
+
process.on('uncaughtException', (err) => {
|
|
15
|
+
console.error('uncaughtException: ', err)
|
|
16
|
+
})
|
|
17
|
+
process.on('unhandledRejection', (err) => {
|
|
18
|
+
console.error('unhandledRejection: ', err)
|
|
19
|
+
})
|
|
20
|
+
|
|
13
21
|
async function start () {
|
|
14
22
|
try {
|
|
15
23
|
// Create an instance of bch-js and IPFS.
|
|
@@ -26,7 +34,7 @@ async function start () {
|
|
|
26
34
|
type: 'node.js',
|
|
27
35
|
// type: 'browser'
|
|
28
36
|
nodeType: 'external',
|
|
29
|
-
debugLevel:
|
|
37
|
+
debugLevel: 2
|
|
30
38
|
})
|
|
31
39
|
|
|
32
40
|
await ipfsCoord.start()
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Production-grade Helia IPFS node factory.
|
|
3
|
+
This library creates and configures a Helia node with libp2p, including:
|
|
4
|
+
- KAD-DHT with custom protocol for private PSF network
|
|
5
|
+
- Bootstrap peer discovery
|
|
6
|
+
- Circuit relay transport and optional circuit relay server
|
|
7
|
+
- Persistent identity via keychain
|
|
8
|
+
- Content routing (libp2pRouting + bitswap)
|
|
9
|
+
- UnixFS file system
|
|
10
|
+
|
|
11
|
+
This is the canonical node configuration used by ipfs-service-provider
|
|
12
|
+
and other consumers of helia-coord.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// Global npm libraries
|
|
16
|
+
import { createHelia } from 'helia'
|
|
17
|
+
import { libp2pRouting } from '@helia/routers'
|
|
18
|
+
import { bitswap } from '@helia/block-brokers'
|
|
19
|
+
import fs from 'fs'
|
|
20
|
+
import { FsBlockstore } from 'blockstore-fs'
|
|
21
|
+
import { FsDatastore } from 'datastore-fs'
|
|
22
|
+
import { createLibp2p } from 'libp2p'
|
|
23
|
+
import { tcp } from '@libp2p/tcp'
|
|
24
|
+
import { noise } from '@chainsafe/libp2p-noise'
|
|
25
|
+
import { yamux } from '@chainsafe/libp2p-yamux'
|
|
26
|
+
import { bootstrap } from '@libp2p/bootstrap'
|
|
27
|
+
import { identify, identifyPush } from '@libp2p/identify'
|
|
28
|
+
import { kadDHT } from '@libp2p/kad-dht'
|
|
29
|
+
import { circuitRelayServer, circuitRelayTransport } from '@libp2p/circuit-relay-v2'
|
|
30
|
+
import { gossipsub } from '@chainsafe/libp2p-gossipsub'
|
|
31
|
+
import { webSockets } from '@libp2p/websockets'
|
|
32
|
+
import { publicIpv4 } from 'public-ip'
|
|
33
|
+
import { multiaddr } from '@multiformats/multiaddr'
|
|
34
|
+
import { webRTC, webRTCDirect } from '@libp2p/webrtc'
|
|
35
|
+
import { keychain } from '@libp2p/keychain'
|
|
36
|
+
import { unixfs } from '@helia/unixfs'
|
|
37
|
+
import { ping } from '@libp2p/ping'
|
|
38
|
+
import { loadOrCreateSelfKey } from '@libp2p/config'
|
|
39
|
+
|
|
40
|
+
// Default PSF bootstrap peers
|
|
41
|
+
const DEFAULT_BOOTSTRAP_PEERS = [
|
|
42
|
+
'/ip4/78.46.129.7/tcp/4001/p2p/12D3KooWEBzgK8a5TpMfLotuj7jJnEK41gbD9LZK6qCpxNrX43E9',
|
|
43
|
+
'/ip4/5.78.70.29/tcp/4001/p2p/12D3KooWSREJ6x2DJSYrA1xRD2Qs6D4DHncsHmNnTHuMKHnqpG2i',
|
|
44
|
+
'/ip4/143.198.134.59/tcp/4101/p2p/12D3KooWHogx3RcyNiSuY6SzS8GxzTAqtDCYzy17yQ1StWaLvX9j'
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
class CreateHeliaNode {
|
|
48
|
+
constructor (localConfig = {}) {
|
|
49
|
+
// Configurable options with production defaults
|
|
50
|
+
this.ipfsDir = localConfig.ipfsDir || './.ipfsdata/ipfs'
|
|
51
|
+
this.tcpPort = localConfig.tcpPort || 4001
|
|
52
|
+
this.wsPort = localConfig.wsPort || 4003
|
|
53
|
+
this.isCircuitRelay = localConfig.isCircuitRelay || false
|
|
54
|
+
this.bootstrapPeers = localConfig.bootstrapPeers || DEFAULT_BOOTSTRAP_PEERS
|
|
55
|
+
|
|
56
|
+
// getSeed is an async function that returns a seed string for keychain.
|
|
57
|
+
// If not provided, a random seed is generated.
|
|
58
|
+
if (localConfig.getSeed) {
|
|
59
|
+
this.getSeed = localConfig.getSeed
|
|
60
|
+
} else {
|
|
61
|
+
this.getSeed = async () => {
|
|
62
|
+
const seedNum = Math.floor(Math.random() * 1000000000000000000000)
|
|
63
|
+
return seedNum.toString()
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Encapsulate dependencies for testing/override
|
|
68
|
+
this.fs = fs
|
|
69
|
+
this.createLibp2p = createLibp2p
|
|
70
|
+
this.createHelia = createHelia
|
|
71
|
+
this.publicIp = publicIpv4
|
|
72
|
+
this.multiaddr = multiaddr
|
|
73
|
+
|
|
74
|
+
// Properties of this class instance
|
|
75
|
+
this.isReady = false
|
|
76
|
+
|
|
77
|
+
// Bind 'this' object to all subfunctions
|
|
78
|
+
this.start = this.start.bind(this)
|
|
79
|
+
this.createNode = this.createNode.bind(this)
|
|
80
|
+
this.stop = this.stop.bind(this)
|
|
81
|
+
this.ensureBlocksDir = this.ensureBlocksDir.bind(this)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Start an IPFS node.
|
|
85
|
+
async start () {
|
|
86
|
+
try {
|
|
87
|
+
// Ensure the directory structure exists that is needed by the IPFS node to store data.
|
|
88
|
+
this.ensureBlocksDir()
|
|
89
|
+
|
|
90
|
+
// Create an IPFS node
|
|
91
|
+
const ipfs = await this.createNode()
|
|
92
|
+
|
|
93
|
+
this.id = ipfs.libp2p.peerId.toString()
|
|
94
|
+
console.log('IPFS ID: ', this.id)
|
|
95
|
+
|
|
96
|
+
// Attempt to guess our ip4 IP address.
|
|
97
|
+
const ip4 = await this.publicIp()
|
|
98
|
+
let detectedMultiaddr = `/ip4/${ip4}/tcp/${this.tcpPort}/p2p/${this.id}`
|
|
99
|
+
detectedMultiaddr = this.multiaddr(detectedMultiaddr)
|
|
100
|
+
|
|
101
|
+
// Get the multiaddrs for the node.
|
|
102
|
+
const multiaddrs = ipfs.libp2p.getMultiaddrs()
|
|
103
|
+
multiaddrs.push(detectedMultiaddr)
|
|
104
|
+
console.log('Multiaddrs: ', multiaddrs)
|
|
105
|
+
|
|
106
|
+
this.multiaddrs = multiaddrs
|
|
107
|
+
|
|
108
|
+
// Signal that this adapter is ready.
|
|
109
|
+
this.isReady = true
|
|
110
|
+
|
|
111
|
+
this.ipfs = ipfs
|
|
112
|
+
|
|
113
|
+
return this.ipfs
|
|
114
|
+
} catch (err) {
|
|
115
|
+
console.error('Error in create-helia-node.js/start()')
|
|
116
|
+
throw err
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// This function creates an IPFS node using Helia.
|
|
121
|
+
// It returns the node as an object.
|
|
122
|
+
async createNode () {
|
|
123
|
+
try {
|
|
124
|
+
const ipfsDir = this.ipfsDir
|
|
125
|
+
|
|
126
|
+
// Create block and data stores.
|
|
127
|
+
const blockstore = new FsBlockstore(`${ipfsDir}/blockstore`)
|
|
128
|
+
const datastore = new FsDatastore(`${ipfsDir}/datastore`)
|
|
129
|
+
|
|
130
|
+
// Create an identity
|
|
131
|
+
const keychainInit = {
|
|
132
|
+
selfKey: 'myKey',
|
|
133
|
+
pass: await this.getSeed()
|
|
134
|
+
}
|
|
135
|
+
const privateKey = await loadOrCreateSelfKey(datastore, keychainInit)
|
|
136
|
+
|
|
137
|
+
// Configure services
|
|
138
|
+
const services = {
|
|
139
|
+
identify: identify(),
|
|
140
|
+
identifyPush: identifyPush(),
|
|
141
|
+
pubsub: gossipsub({ allowPublishToZeroTopicPeers: true }),
|
|
142
|
+
ping: ping(),
|
|
143
|
+
keychain: keychain(keychainInit),
|
|
144
|
+
dht: kadDHT({
|
|
145
|
+
protocol: '/psf/kad/1.0.0',
|
|
146
|
+
clientMode: false
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Conditionally add circuit relay server
|
|
151
|
+
if (this.isCircuitRelay) {
|
|
152
|
+
console.log('Helia (IPFS) node IS configured as Circuit Relay')
|
|
153
|
+
services.relay = circuitRelayServer({
|
|
154
|
+
hopTimeout: 30 * 1000,
|
|
155
|
+
reservations: {
|
|
156
|
+
maxReservations: 15,
|
|
157
|
+
reservationClearInterval: 300 * 1000,
|
|
158
|
+
applyDefaultLimit: true,
|
|
159
|
+
defaultDurationLimit: 2 * 60 * 1000,
|
|
160
|
+
defaultDataLimit: BigInt(2 << 7)
|
|
161
|
+
},
|
|
162
|
+
maxInboundHopStreams: 32,
|
|
163
|
+
maxOutboundHopStreams: 64
|
|
164
|
+
})
|
|
165
|
+
} else {
|
|
166
|
+
console.log('Helia (IPFS) node IS NOT configured as Circuit Relay')
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const transports = [
|
|
170
|
+
tcp(),
|
|
171
|
+
webSockets(),
|
|
172
|
+
circuitRelayTransport({
|
|
173
|
+
discoverRelays: 3,
|
|
174
|
+
reservationConcurrency: 3
|
|
175
|
+
}),
|
|
176
|
+
webRTC(),
|
|
177
|
+
webRTCDirect()
|
|
178
|
+
]
|
|
179
|
+
|
|
180
|
+
// libp2p is the networking layer that underpins Helia
|
|
181
|
+
const libp2p = await this.createLibp2p({
|
|
182
|
+
privateKey,
|
|
183
|
+
datastore,
|
|
184
|
+
addresses: {
|
|
185
|
+
listen: [
|
|
186
|
+
'/ip4/127.0.0.1/tcp/0',
|
|
187
|
+
`/ip4/0.0.0.0/tcp/${this.tcpPort}`,
|
|
188
|
+
`/ip4/0.0.0.0/tcp/${this.wsPort}/ws`,
|
|
189
|
+
'/webrtc',
|
|
190
|
+
'/p2p-circuit'
|
|
191
|
+
]
|
|
192
|
+
},
|
|
193
|
+
transports,
|
|
194
|
+
connectionEncrypters: [
|
|
195
|
+
noise()
|
|
196
|
+
],
|
|
197
|
+
streamMuxers: [
|
|
198
|
+
yamux()
|
|
199
|
+
],
|
|
200
|
+
peerDiscovery: [
|
|
201
|
+
bootstrap({
|
|
202
|
+
list: this.bootstrapPeers
|
|
203
|
+
})
|
|
204
|
+
],
|
|
205
|
+
services
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
// create a Helia node
|
|
209
|
+
const helia = await this.createHelia({
|
|
210
|
+
blockstore,
|
|
211
|
+
datastore,
|
|
212
|
+
libp2p,
|
|
213
|
+
routers: [
|
|
214
|
+
libp2pRouting(libp2p)
|
|
215
|
+
],
|
|
216
|
+
blockBrokers: [
|
|
217
|
+
bitswap()
|
|
218
|
+
]
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
// Attach IPFS file system.
|
|
222
|
+
const heliaFs = unixfs(helia)
|
|
223
|
+
helia.fs = heliaFs
|
|
224
|
+
|
|
225
|
+
return helia
|
|
226
|
+
} catch (err) {
|
|
227
|
+
console.error('Error creating Helia node: ', err)
|
|
228
|
+
throw err
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
async stop () {
|
|
233
|
+
await this.ipfs.stop()
|
|
234
|
+
|
|
235
|
+
return true
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Ensure that the directories exist to store blocks from the IPFS network.
|
|
239
|
+
// This function is called at startup, before the IPFS node is started.
|
|
240
|
+
ensureBlocksDir () {
|
|
241
|
+
try {
|
|
242
|
+
const ipfsDir = this.ipfsDir
|
|
243
|
+
const parentDir = ipfsDir.substring(0, ipfsDir.lastIndexOf('/'))
|
|
244
|
+
|
|
245
|
+
!this.fs.existsSync(parentDir) && this.fs.mkdirSync(parentDir, { recursive: true })
|
|
246
|
+
|
|
247
|
+
!this.fs.existsSync(ipfsDir) && this.fs.mkdirSync(ipfsDir, { recursive: true })
|
|
248
|
+
|
|
249
|
+
!this.fs.existsSync(`${ipfsDir}/blockstore`) && this.fs.mkdirSync(`${ipfsDir}/blockstore`)
|
|
250
|
+
|
|
251
|
+
!this.fs.existsSync(`${ipfsDir}/datastore`) && this.fs.mkdirSync(`${ipfsDir}/datastore`)
|
|
252
|
+
|
|
253
|
+
!this.fs.existsSync(`${ipfsDir}/datastore/pkcs8`) && this.fs.mkdirSync(`${ipfsDir}/datastore/pkcs8`)
|
|
254
|
+
|
|
255
|
+
return true
|
|
256
|
+
} catch (err) {
|
|
257
|
+
console.error('Error in create-helia-node.js/ensureBlocksDir(): ', err)
|
|
258
|
+
throw err
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export default CreateHeliaNode
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "helia-coord",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A JS library for helping IPFS peers coordinate, find a common interest, and stay connected around that interest.",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -20,48 +20,53 @@
|
|
|
20
20
|
},
|
|
21
21
|
"homepage": "https://github.com/Permissionless-Software-Foundation/helia-coord#readme",
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@chainsafe/libp2p-gossipsub": "14.1.0",
|
|
24
|
-
"@chainsafe/libp2p-noise": "16.0.1",
|
|
25
|
-
"@chainsafe/libp2p-yamux": "7.0.1",
|
|
26
23
|
"@istanbuljs/esm-loader-hook": "0.2.0",
|
|
27
|
-
"@libp2p/circuit-relay-v2": "3.2.2",
|
|
28
|
-
"@libp2p/identify": "3.0.22",
|
|
29
|
-
"@libp2p/ping": "2.0.22",
|
|
30
|
-
"@libp2p/tcp": "10.1.2",
|
|
31
|
-
"@libp2p/webrtc": "5.2.2",
|
|
32
|
-
"@libp2p/websockets": "9.2.2",
|
|
33
|
-
"@multiformats/multiaddr": "12.3.5",
|
|
34
|
-
"blockstore-fs": "2.0.2",
|
|
35
24
|
"chai": "4.3.6",
|
|
36
25
|
"cross-env": "7.0.3",
|
|
37
|
-
"datastore-fs": "10.0.2",
|
|
38
26
|
"delay": "6.0.0",
|
|
39
|
-
"helia": "5.2.1",
|
|
40
|
-
"libp2p": "2.7.2",
|
|
41
27
|
"lodash.clonedeep": "4.5.0",
|
|
42
28
|
"minimal-slp-wallet": "7.1.4",
|
|
43
29
|
"mocha": "10.0.0",
|
|
44
30
|
"nyc": "15.1.0",
|
|
45
|
-
"public-ip": "6.0.1",
|
|
46
31
|
"sinon": "14.0.0",
|
|
47
32
|
"standard": "17.0.0"
|
|
48
33
|
},
|
|
49
34
|
"overrides": {
|
|
50
35
|
"@multiformats/multiaddr-to-uri": "10.1.2",
|
|
51
36
|
"@multiformats/multiaddr-matcher": "1.6.0",
|
|
37
|
+
"@libp2p/utils": "6.7.1",
|
|
52
38
|
"helia": {
|
|
53
39
|
"libp2p": "2.7.2",
|
|
54
40
|
"@libp2p/upnp-nat": "3.0.0"
|
|
55
41
|
}
|
|
56
42
|
},
|
|
57
43
|
"dependencies": {
|
|
44
|
+
"@chainsafe/libp2p-gossipsub": "14.1.0",
|
|
45
|
+
"@chainsafe/libp2p-noise": "16.0.1",
|
|
46
|
+
"@chainsafe/libp2p-yamux": "7.0.1",
|
|
58
47
|
"@chris.troutner/retry-queue": "1.0.10",
|
|
48
|
+
"@helia/block-brokers": "4.0.4",
|
|
49
|
+
"@helia/routers": "3.0.0",
|
|
50
|
+
"@helia/unixfs": "4.0.2",
|
|
51
|
+
"@libp2p/bootstrap": "11.0.20",
|
|
52
|
+
"@libp2p/circuit-relay-v2": "3.2.2",
|
|
53
|
+
"@libp2p/config": "1.1.0",
|
|
54
|
+
"@libp2p/identify": "3.0.22",
|
|
55
|
+
"@libp2p/kad-dht": "14.2.3",
|
|
56
|
+
"@libp2p/keychain": "5.0.14",
|
|
57
|
+
"@libp2p/ping": "2.0.22",
|
|
58
|
+
"@libp2p/tcp": "10.1.2",
|
|
59
|
+
"@libp2p/webrtc": "5.2.2",
|
|
60
|
+
"@libp2p/websockets": "9.2.2",
|
|
61
|
+
"@multiformats/multiaddr": "12.3.5",
|
|
59
62
|
"bch-encrypt-lib": "2.1.1",
|
|
63
|
+
"blockstore-fs": "2.0.2",
|
|
64
|
+
"datastore-fs": "10.0.2",
|
|
65
|
+
"helia": "5.2.1",
|
|
66
|
+
"libp2p": "2.7.2",
|
|
67
|
+
"public-ip": "6.0.1",
|
|
60
68
|
"uuid": "9.0.0"
|
|
61
69
|
},
|
|
62
|
-
"peerDependencies": {
|
|
63
|
-
"libp2p": "=2.7.2"
|
|
64
|
-
},
|
|
65
70
|
"exports": {
|
|
66
71
|
".": {
|
|
67
72
|
"import": {
|
|
@@ -72,6 +77,14 @@
|
|
|
72
77
|
"require": {
|
|
73
78
|
"default": "./index.js"
|
|
74
79
|
}
|
|
80
|
+
},
|
|
81
|
+
"./create-helia-node": {
|
|
82
|
+
"import": {
|
|
83
|
+
"default": "./lib/create-helia-node.js"
|
|
84
|
+
},
|
|
85
|
+
"require": {
|
|
86
|
+
"default": "./lib/create-helia-node.js"
|
|
87
|
+
}
|
|
75
88
|
}
|
|
76
89
|
}
|
|
77
90
|
}
|