helia-coord 2.0.1 → 2.0.3
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 +169 -2
- package/dev-docs/pubsub.md +25 -1
- package/dev-docs/startup.md +9 -3
- package/dev-docs/temp.md +2 -2
- package/dev-docs/theory-of-operation.md +1 -1
- package/dev-docs/usage-and-code.md +39 -25
- package/lib/create-helia-node.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,172 @@
|
|
|
1
1
|
# helia-coord
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A JavaScript npm library built on top of [Helia](https://github.com/ipfs/helia), the JS implementation of IPFS. It provides the following high-level features:
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- **Subnets** - Helps IPFS nodes create an on-the-fly subnetwork, using pubsub channels.
|
|
6
|
+
- **Peer Discovery** - Allows new peers entering the subnetwork to find the other subnetwork peers.
|
|
7
|
+
- **E2EE** - Creates end-to-end encrypted (e2ee) communication channels between peers.
|
|
8
|
+
- **Censorship Resistance** - Allows automatic networking between peers, even if they are behind a firewall.
|
|
9
|
+
- **Payments** - Allows peers to easily pay one another in cryptocurrency for access to web services.
|
|
10
|
+
|
|
11
|
+
This library helps IPFS peers discover one another, coordinate around a common interest, and then stay connected around that interest. Its main sub-components are:
|
|
12
|
+
|
|
13
|
+
- [libp2p](https://libp2p.io/) pubsub channels (via [gossipsub](https://github.com/ChainSafe/js-libp2p-gossipsub)) for communication
|
|
14
|
+
- [Circuit Relays](https://docs.libp2p.io/concepts/nat/circuit-relay/) for censorship resistance and tunneling through firewalls
|
|
15
|
+
- [Bitcoin Cash](https://bitcoincash.org/) for end-to-end encryption and payments
|
|
16
|
+
|
|
17
|
+
helia-coord will automatically track peers, connect to them through circuit relays, and end-to-end encrypt all communication with each node. Interval timers continually maintain these connections, creating a self-healing mesh network. For more details, read the [dev-docs](./dev-docs).
|
|
18
|
+
|
|
19
|
+
Here are some use cases where IPFS node coordination is needed:
|
|
20
|
+
|
|
21
|
+
- e2e encrypted chat
|
|
22
|
+
- Circuit-relay as-a-service
|
|
23
|
+
- Creating CoinJoin transactions
|
|
24
|
+
- Decentralized exchange of currencies
|
|
25
|
+
- Compute-as-a-service
|
|
26
|
+
- Storage-as-a-service
|
|
27
|
+
|
|
28
|
+
The ultimate goal of this library is to be a building block for replacing conventional REST APIs. An IPFS-based API, in a fully distributed network like IPFS, must have sophisticated coordination in order to function properly. helia-coord is that coordination library. It is consumed by higher-level applications like [ipfs-service-provider](https://github.com/Permissionless-Software-Foundation/ipfs-service-provider).
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
Install the npm library:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install --save helia-coord
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
This library requires a peer dependency of [minimal-slp-wallet](https://www.npmjs.com/package/minimal-slp-wallet).
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
helia-coord exports two things:
|
|
43
|
+
|
|
44
|
+
- **`IpfsCoord`** (default export) - The coordination library that wraps a Helia IPFS node.
|
|
45
|
+
- **`CreateHeliaNode`** (via `helia-coord/create-helia-node`) - A factory class for creating a properly configured Helia IPFS node.
|
|
46
|
+
|
|
47
|
+
### Example in a node.js app
|
|
48
|
+
|
|
49
|
+
Here is an example of adding helia-coord to your own node.js app:
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
import SlpWallet from 'minimal-slp-wallet'
|
|
53
|
+
import IpfsCoord from 'helia-coord'
|
|
54
|
+
import CreateHeliaNode from 'helia-coord/create-helia-node'
|
|
55
|
+
|
|
56
|
+
async function start () {
|
|
57
|
+
// Create an instance of the BCH wallet.
|
|
58
|
+
const wallet = new SlpWallet()
|
|
59
|
+
await wallet.walletInfoPromise
|
|
60
|
+
|
|
61
|
+
// Create a Helia IPFS node.
|
|
62
|
+
const createHeliaNode = new CreateHeliaNode()
|
|
63
|
+
const ipfs = await createHeliaNode.start()
|
|
64
|
+
|
|
65
|
+
// Pass the wallet and IPFS node to helia-coord when instantiating it.
|
|
66
|
+
const ipfsCoord = new IpfsCoord({
|
|
67
|
+
ipfs,
|
|
68
|
+
wallet,
|
|
69
|
+
type: 'node.js',
|
|
70
|
+
debugLevel: 1
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
await ipfsCoord.start()
|
|
74
|
+
console.log('IPFS and the coordination library is ready.')
|
|
75
|
+
}
|
|
76
|
+
start()
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
See [`examples/start-node.js`](./examples/start-node.js) for a working example.
|
|
80
|
+
|
|
81
|
+
## Configuration
|
|
82
|
+
|
|
83
|
+
When instantiating `IpfsCoord`, the following configuration properties can be passed to its constructor:
|
|
84
|
+
|
|
85
|
+
| Property | Required | Description |
|
|
86
|
+
|---|---|---|
|
|
87
|
+
| `ipfs` | Yes | An instance of a [Helia](https://github.com/ipfs/helia) IPFS node. |
|
|
88
|
+
| `wallet` | Yes | An instance of [minimal-slp-wallet](https://www.npmjs.com/package/minimal-slp-wallet). Used for BCH payments and generating encryption keys. |
|
|
89
|
+
| `type` | Yes | `'node.js'` or `'browser'` - the type of environment the app is running in. |
|
|
90
|
+
| `debugLevel` | No | Integer from 0-3. `0` = no debug output (default), `1` = status logs, `2` = verbose connection errors, `3` = everything. |
|
|
91
|
+
| `statusLog` | No | A function for handling status log messages. Defaults to `console.log`. |
|
|
92
|
+
| `privateLog` | No | A function for handling incoming e2e encrypted private messages from other peers. Defaults to `console.log`. |
|
|
93
|
+
| `nodeType` | No | `'embedded'` (default) or `'external'`. |
|
|
94
|
+
| `isCircuitRelay` | No | Boolean. Set to `true` if this node should act as a Circuit Relay. Defaults to `false`. |
|
|
95
|
+
| `circuitRelayInfo` | No | Object with additional info for circuit relay nodes (e.g. `{ ip4, tcpPort, crDomain }`). |
|
|
96
|
+
| `announceJsonLd` | No | A custom [JSON-LD](https://json-ld.org/) object for the node's announcement. Overrides the default. |
|
|
97
|
+
| `tcpPort` | No | TCP port number. Used for auto-detecting the node's public multiaddr. |
|
|
98
|
+
| `apiInfo` | No | A string (URL or IPFS hash) pointing to API documentation for the service this node provides. |
|
|
99
|
+
|
|
100
|
+
When instantiating `CreateHeliaNode`, the following configuration properties can be passed:
|
|
101
|
+
|
|
102
|
+
| Property | Default | Description |
|
|
103
|
+
|---|---|---|
|
|
104
|
+
| `ipfsDir` | `'./.ipfsdata/ipfs'` | Directory for IPFS block and data stores. |
|
|
105
|
+
| `tcpPort` | `4001` | TCP port for libp2p to listen on. |
|
|
106
|
+
| `wsPort` | `4003` | WebSocket port for libp2p to listen on. |
|
|
107
|
+
| `isCircuitRelay` | `false` | Whether to enable the circuit relay server. |
|
|
108
|
+
| `bootstrapPeers` | PSF defaults | Array of multiaddr strings for bootstrap peer discovery. |
|
|
109
|
+
| `getSeed` | Random | An async function returning a seed string for the libp2p keychain. Provide this to get a persistent IPFS peer ID across restarts. |
|
|
110
|
+
|
|
111
|
+
## Development Environment
|
|
112
|
+
|
|
113
|
+
Clone the repository and install dependencies:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
git clone https://github.com/Permissionless-Software-Foundation/helia-coord
|
|
117
|
+
cd helia-coord
|
|
118
|
+
npm install
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Running Tests
|
|
122
|
+
|
|
123
|
+
This project uses [Mocha](https://mochajs.org/) for testing, [Chai](https://www.chaijs.com/) for assertions, [Sinon](https://sinonjs.org/) for mocks, and [nyc](https://github.com/istanbuljs/nyc) for code coverage.
|
|
124
|
+
|
|
125
|
+
Run the unit test suite:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
npm test
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
This runs the linter ([Standard.js](https://standardjs.com/)) followed by the unit tests.
|
|
132
|
+
|
|
133
|
+
Generate a coverage report:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npm run coverage:report
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Running the Example App
|
|
140
|
+
|
|
141
|
+
The `examples/` directory contains a working example that starts a Helia IPFS node with helia-coord attached:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
cd examples
|
|
145
|
+
node start-node.js
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
This will create a Helia IPFS node, connect to the PSF coordination network, discover peers, and begin announcing itself on the pubsub coordination channel. IPFS data is stored in `examples/.ipfsdata/`.
|
|
149
|
+
|
|
150
|
+
## Architecture
|
|
151
|
+
|
|
152
|
+
helia-coord follows the [Clean Architecture](https://troutsblog.com/blog/clean-architecture) design pattern, organized into four layers:
|
|
153
|
+
|
|
154
|
+
- **Entities** - Core business objects: `thisNode` (the local IPFS node), `peers` (other nodes on the subnet), `relays` (circuit relay nodes), and `pubsub` channels.
|
|
155
|
+
- **Use Cases** - Actions performed on entities: creating the node identity, managing peer connections, handling relay connections, and initializing pubsub.
|
|
156
|
+
- **Controllers** - Inputs to the system, primarily interval timers that periodically maintain connections, announce the node, and manage peer/relay state.
|
|
157
|
+
- **Adapters** - Interfaces to external systems: IPFS (Helia/libp2p), BCH (minimal-slp-wallet), encryption (Elliptic Curve), pubsub messaging, and a GitHub Gist adapter for discovering circuit relays.
|
|
158
|
+
|
|
159
|
+
After instantiation, the library exposes `useCases`, `controllers`, and `adapters` properties for programmatic access to its features.
|
|
160
|
+
|
|
161
|
+
## Further Reading
|
|
162
|
+
|
|
163
|
+
- [dev-docs/theory-of-operation.md](./dev-docs/theory-of-operation.md) - High-level overview of entities, pubsub channels, and interval timers.
|
|
164
|
+
- [dev-docs/usage-and-code.md](./dev-docs/usage-and-code.md) - Detailed specifications for the Clean Architecture layers.
|
|
165
|
+
- [Helia](https://github.com/ipfs/helia) - The JavaScript IPFS implementation that helia-coord wraps.
|
|
166
|
+
- [ipfs-service-provider](https://github.com/Permissionless-Software-Foundation/ipfs-service-provider) - A higher-level application that consumes helia-coord.
|
|
167
|
+
- [The Cash Stack](https://cashstack.info) - The full software stack that helia-coord is a part of.
|
|
168
|
+
- [PSFoundation.cash](https://PSFoundation.cash) - The Permissionless Software Foundation.
|
|
169
|
+
|
|
170
|
+
## License
|
|
171
|
+
|
|
172
|
+
[MIT](LICENSE.md)
|
package/dev-docs/pubsub.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
1
|
# Pubsub
|
|
2
2
|
|
|
3
|
-
One of the primary functions of the helia-coord library is
|
|
3
|
+
One of the primary functions of the helia-coord library is managing pubsub channels for communication between IPFS nodes. See [theory-of-operation.md](./theory-of-operation.md) for a high-level overview of the channel types.
|
|
4
|
+
|
|
5
|
+
## Coordination Channel
|
|
6
|
+
|
|
7
|
+
All nodes on the subnet subscribe to a shared coordination channel (configured in `config/global-config.js` as `DEFAULT_COORDINATION_ROOM`). Nodes periodically broadcast an announcement object on this channel containing their IPFS ID, multiaddrs, public encryption key, BCH/SLP addresses, and JSON-LD metadata. When a node receives an announcement, it is routed to `addSubnetPeer()` in `peer-use-cases.js` to be processed.
|
|
8
|
+
|
|
9
|
+
## Private Channels
|
|
10
|
+
|
|
11
|
+
Each node subscribes to a pubsub channel named after its own IPFS peer ID. This channel is used exclusively for **receiving** encrypted messages from other peers. The node never broadcasts on its own private channel.
|
|
12
|
+
|
|
13
|
+
When a new peer is discovered via the coordination channel, the node subscribes to that peer's private channel in order to **send** encrypted messages to it. Messages are encrypted with the recipient's public key using Elliptic Curve cryptography (via `encryption-adapter.js`) before being published.
|
|
14
|
+
|
|
15
|
+
Incoming encrypted messages on the private channel are decrypted and then passed up to the consuming application via the `privateLog` callback. Low-level messages such as ACK and metric commands are handled internally by helia-coord and are not passed up.
|
|
16
|
+
|
|
17
|
+
## Message Routing
|
|
18
|
+
|
|
19
|
+
The pubsub adapter (`lib/adapters/pubsub-adapter/`) handles message routing:
|
|
20
|
+
|
|
21
|
+
- `messaging.js` - Publishes messages to pubsub channels.
|
|
22
|
+
- `msg-router.js` - Routes incoming messages to the appropriate handler based on the channel and message type.
|
|
23
|
+
- `resend-msg.js` - Handles retrying failed message deliveries.
|
|
24
|
+
|
|
25
|
+
## CoinJoin Channel
|
|
26
|
+
|
|
27
|
+
A separate pubsub channel (`BCH_COINJOIN_ROOM` in the global config) exists for coordinating CoinJoin transactions for financial privacy. This channel is not fully developed and can be ignored for now.
|
package/dev-docs/startup.md
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
# Startup
|
|
2
2
|
|
|
3
|
-
Outline of startup procedure
|
|
3
|
+
Outline of the startup procedure for helia-coord. See [theory-of-operation.md](./theory-of-operation.md) for a high-level overview and [usage-and-code.md](./usage-and-code.md) for details on each architectural layer.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
1. The consuming application creates a Helia IPFS node (e.g. via `CreateHeliaNode`) and an instance of `minimal-slp-wallet`.
|
|
6
|
+
2. The consuming application instantiates `IpfsCoord`, passing in the Helia node, wallet, and configuration options.
|
|
7
|
+
3. The consuming application calls `ipfsCoord.start()`, which triggers the following sequence:
|
|
8
|
+
- The IPFS adapter starts and retrieves the node's peer ID and multiaddrs.
|
|
9
|
+
- `createSelf()` builds the `thisNode` entity by aggregating IPFS info, generating BCH/SLP addresses and a public encryption key from the wallet, initializing the Schema library, and subscribing to the node's own private pubsub channel.
|
|
10
|
+
- `initializePubsub()` subscribes the node to the general coordination pubsub channel.
|
|
11
|
+
- `startTimers()` initializes the interval timers that maintain connections to relays, announce the node, and manage peer connections.
|
|
12
|
+
- `_initializeConnections()` downloads the Circuit Relay list from the GitHub Gist and attempts initial connections to relays and subnet peers. This runs without blocking so it does not delay startup of the consuming application.
|
package/dev-docs/temp.md
CHANGED
|
@@ -15,9 +15,9 @@ Peers are other IPFS nodes that the application wants to keep track of. These ar
|
|
|
15
15
|
|
|
16
16
|
### Relays
|
|
17
17
|
|
|
18
|
-
Some nodes using
|
|
18
|
+
Some nodes using helia-coord can elect to become [Circuit Relays](https://docs.libp2p.io/concepts/circuit-relay/). Circuit Relays are critical for keeping the network censorship resistant. They allow nodes that otherwise would not be able to communicate with one another, do so. They assist in punching through network firewalls that would otherwise block communication. They allow the subnet to route around damage and dynamically adjust as nodes enter and leave the subnet.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
helia-coord will start by connecting to a small set of pre-configured Relays. As it discovers new peers in the subnetwork that have their `isCircuitRelay` flag set, it will expand its connections to as many Relays as it can find.
|
|
21
21
|
|
|
22
22
|
- `relayList` - An array of IPFS IDs (strings), identifying each Relay this node knows about.
|
|
23
23
|
- `relayData` - An object with root properties that match the relay IPFS ID. Each root property represents a relay and contains the data about that relay.
|
|
@@ -49,4 +49,4 @@ There are some low-level messages that are not passed up to the consuming softwa
|
|
|
49
49
|
When a new node is discovered via its announcement on the *Coordination Channel*, the node will subscribe to that nodes private channel. The node will use this channel to send encrypted RPC commands to other nodes. This channel is only used for broadcasting. It is never used for receiving messages.
|
|
50
50
|
|
|
51
51
|
## Interval Timers
|
|
52
|
-
A series of interval timers are defined in the `lib/
|
|
52
|
+
A series of interval timers are defined in the `lib/controllers/timer-controller.js` file. These timers are periodically triggered in order to maintain the nodes state. They renew broken connections to other nodes, track latency between the node and Circuit Relays that it knows about, and other operations. These time-based function calls are what allow the node to create the mesh network on-the-fly and the self-heal the network as nodes come online or drop off the network.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# helia-coord Specifications
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
helia-coord is a shortening of the word 'coordination'. It is a JavaScript npm library that helps applications using [Helia](https://github.com/ipfs/helia) coordinate with other peers running related applications.
|
|
6
6
|
|
|
7
|
-
This document contains a high-level, human-readable specification for the four major architectural areas of the
|
|
7
|
+
This document contains a high-level, human-readable specification for the four major architectural areas of the helia-coord library:
|
|
8
8
|
|
|
9
9
|
- Entities
|
|
10
10
|
- Use Cases
|
|
@@ -13,17 +13,23 @@ This document contains a high-level, human-readable specification for the four m
|
|
|
13
13
|
|
|
14
14
|
This reflects the [Clean Architecture](https://troutsblog.com/blog/clean-architecture) design pattern.
|
|
15
15
|
|
|
16
|
-
After the
|
|
16
|
+
After the helia-coord library is instantiated, it will have properties `useCases`, `controllers`, and `adapters` that have methods corresponding to the descriptions in this document. Apps can exercise the features of the helia-coord library through this object-oriented structure.
|
|
17
17
|
|
|
18
18
|
## Configuration
|
|
19
19
|
|
|
20
|
-
When instantiating the
|
|
20
|
+
When instantiating the helia-coord library, the following configuration inputs can be passed to its constructor via an object with the properties indicated below. Be sure to check out the [examples directory](../examples) for examples on how to instantiate the library with different configurations.
|
|
21
21
|
|
|
22
|
-
- `ipfs`: (required) An instance of [
|
|
23
|
-
- `
|
|
22
|
+
- `ipfs`: (required) An instance of [Helia](https://github.com/ipfs/helia). The Helia IPFS node must be instantiated outside of helia-coord and passed into it when instantiating the library.
|
|
23
|
+
- `wallet`: (required) An instance of [minimal-slp-wallet](https://www.npmjs.com/package/minimal-slp-wallet). The wallet must be instantiated outside of helia-coord and passed into it when instantiating the library. It provides BCH address generation and encryption key management.
|
|
24
24
|
- `type`: (required) A string with the value of 'browser' or 'node.js', to indicate what type of app is instantiating the library. This will determine the types of Circuit Relays the library can connect to.
|
|
25
|
-
- `statusLog`: A function for handling status output strings on the status of
|
|
25
|
+
- `statusLog`: A function for handling status output strings on the status of helia-coord. This defaults to `console.log` if not specified.
|
|
26
26
|
- `privateLog`: A function for handling private messages passed to this node from peer nodes. This defaults to `console.log` if not specified.
|
|
27
|
+
- `debugLevel`: An integer from 0-3 controlling the verbosity of log output. `0` = no debug output (default), `1` = status logs, `2` = verbose connection errors, `3` = everything.
|
|
28
|
+
- `isCircuitRelay`: A boolean indicating whether this node should act as a Circuit Relay. Defaults to `false`.
|
|
29
|
+
- `circuitRelayInfo`: An object with additional info for circuit relay nodes (e.g. `{ ip4, tcpPort, crDomain }`).
|
|
30
|
+
- `announceJsonLd`: A custom JSON-LD object for the node's announcement on the coordination channel. Overrides the default.
|
|
31
|
+
- `tcpPort`: TCP port number. Used for auto-detecting the node's public multiaddr.
|
|
32
|
+
- `apiInfo`: A string (URL or IPFS hash) pointing to API documentation for the service this node provides.
|
|
27
33
|
|
|
28
34
|
## Entities
|
|
29
35
|
|
|
@@ -31,7 +37,7 @@ Entities make up the core business concepts. If these entities change, they fund
|
|
|
31
37
|
|
|
32
38
|
### thisNode
|
|
33
39
|
|
|
34
|
-
`thisNode` is the IPFS node consuming the
|
|
40
|
+
`thisNode` is the IPFS node consuming the helia-coord library. The thisNode Entity creates a representation of the 'self' and maintains the state of the IPFS node, BCH wallet, peers, relays, and pubsub channels that the node is tracking.
|
|
35
41
|
|
|
36
42
|
## Use Cases
|
|
37
43
|
|
|
@@ -44,19 +50,27 @@ The `this-node-use-cases.js` library contains the following Use Cases:
|
|
|
44
50
|
- `createSelf()` - initializes the `thisNode` Entity. It takes the following actions:
|
|
45
51
|
|
|
46
52
|
- It retrieves basic information about the IPFS node like the ID and multiaddresses.
|
|
47
|
-
- It
|
|
48
|
-
- It
|
|
53
|
+
- It generates BCH and SLP addresses (via the wallet) for payments and a public key used for end-to-end encryption (e2ee).
|
|
54
|
+
- It subscribes to its own private pubsub channel for receiving encrypted messages from other peers.
|
|
49
55
|
- It initializes the Schema library for passing standardized messages.
|
|
50
56
|
|
|
51
|
-
|
|
57
|
+
### Peers
|
|
58
|
+
|
|
59
|
+
The `peer-use-cases.js` library contains the following Use Cases:
|
|
60
|
+
|
|
61
|
+
- `addSubnetPeer()` - This is an event handler that is triggered when an 'announcement object' is received on the general coordination pubsub channel. That object is passed to `addSubnetPeer()` to be processed. It will analyze the announcement object and add the peer to the array of peers tracked by the thisNode Entity. If the peer is already known, its data will be updated.
|
|
52
62
|
|
|
53
63
|
- `refreshPeerConnections()` - is periodically called by the Timer Controller. It checks to see if thisNode is still connected to all the subnet peers. It will refresh the connection if they have been disconnected. Circuit Relays are used to connect to other subnet peers, and each known circuit relay will be cycled through until a connection can be established between thisNode and the subnet peer.
|
|
54
64
|
|
|
65
|
+
- `sendPrivateMessage()` - sends an encrypted message to another peer on the subnet via their private pubsub channel.
|
|
66
|
+
|
|
55
67
|
### Relays
|
|
56
68
|
|
|
57
69
|
The `relay-use-cases.js` library controls the interactions between thisNode and the Circuit Relays that it knows about.
|
|
58
70
|
|
|
59
|
-
- `
|
|
71
|
+
- `getCRGist()` - At startup, helia-coord downloads a list of Circuit Relay nodes from a GitHub Gist (via the Gist adapter). It then attempts to connect to each relay in the list. This is what 'bootstraps' thisNode to the IPFS sub-network and allows it to find subnetwork peers. After that initial bootstrap connection, thisNode will automatically learn about and connect to other peers and circuit relays.
|
|
72
|
+
|
|
73
|
+
- `connectToBootstrapRelays()` - Connects to the bootstrap peers configured in the libp2p setup. These are peers that are known to run as v2 Circuit Relays and can facilitate connections between other peers.
|
|
60
74
|
|
|
61
75
|
- `connectToCRs()` - This method is called periodically by the Timer Controller. It checks the connection between thisNode and each Circuit Relay node. If thisNode has lost its connection, the connection is restored.
|
|
62
76
|
|
|
@@ -64,7 +78,7 @@ The `relay-use-cases.js` library controls the interactions between thisNode and
|
|
|
64
78
|
|
|
65
79
|
The `pubsub-use-cases.js` has a single method:
|
|
66
80
|
|
|
67
|
-
- `initializePubsub()` is called at startup to connect the node to the general coordination pubsub channel. This is the channel where other apps running the
|
|
81
|
+
- `initializePubsub()` is called at startup to connect the node to the general coordination pubsub channel. This is the channel where other apps running the helia-coord library announce themselves to other peers in the subnet.
|
|
68
82
|
|
|
69
83
|
## Controllers
|
|
70
84
|
|
|
@@ -82,34 +96,34 @@ The controllers listed in this section are activated periodically by a timer. Th
|
|
|
82
96
|
|
|
83
97
|
- `managePeers()` checks the list of known subnet peers tracked by thisNode Entity. It will restore the connection to each peer if they get disconnected.
|
|
84
98
|
|
|
99
|
+
- `getWebRtcMultiaddr()` extracts any webRTC multiaddrs from the node's list of multiaddrs and adds them to the announcement object.
|
|
100
|
+
|
|
85
101
|
## Adapters
|
|
86
102
|
|
|
87
103
|
Adapters are the 'outputs' of the system. They are the interfaces that this library manipulates in order to maintain the state of the Entities. Adapters ensure that the business logic doesn't need to know any specific information about the outputs.
|
|
88
104
|
|
|
89
105
|
### bch-adapter.js
|
|
90
106
|
|
|
91
|
-
[
|
|
107
|
+
The BCH adapter uses [minimal-slp-wallet](https://www.npmjs.com/package/minimal-slp-wallet) (via its embedded bch-js library) to handle payments and end-to-end encryption in peer communication. When the IPFS node is started, it generates a BCH address to receive payments in BCH, and an SLP address to receive payments in SLP tokens. The same private key used to generate these addresses is used to decrypt incoming pubsub messages, and the public key is passed on to other peers so that they can encrypt messages they want to send thisNode.
|
|
92
108
|
|
|
93
109
|
### ipfs-adapter.js
|
|
94
110
|
|
|
95
|
-
This library is designed primarily to control an IPFS node. However, it does not load IPFS directly. It expects the developer to inject an instance of
|
|
96
|
-
|
|
97
|
-
### orbitdb-adapter.js
|
|
98
|
-
|
|
99
|
-
[OrbitDB](https://orbitdb.org/) is a database that runs on top of IPFS. It's used in this library to prevent 'dropped calls'. As nodes are constantly adjusting their network connections, they can sometimes miss pubsub messages. Other peers in the subnet maintain short-lived logs of the encrypted messages directed at the peers they are connected to. This allows them to pass the message on when the peer reconnects to them, preventing 'dropped calls'. These logs are abandoned after an hour and a new log is created, to prevent them from growing too large.
|
|
111
|
+
This library is designed primarily to control an IPFS node. However, it does not load IPFS directly. It expects the developer to inject an instance of Helia when instantiating this library. It uses the Helia node's underlying libp2p layer for peer management, including connecting, disconnecting, and listing peers.
|
|
100
112
|
|
|
101
113
|
### encryption-adapter.js
|
|
102
114
|
|
|
103
|
-
The encryption adapter is responsible for encryption and decryption of pubsub messages. It uses the same
|
|
115
|
+
The encryption adapter is responsible for encryption and decryption of pubsub messages. It uses the same Elliptic Curve cryptography used by the Bitcoin protocol. The same private key that is used to generate the BCH address assigned to thisNode is the same private key used to decrypt incoming messages.
|
|
104
116
|
|
|
105
|
-
Other subnet peers that thisNode tracks will pass on their public key. All messages sent between nodes
|
|
117
|
+
Other subnet peers that thisNode tracks will pass on their public key. All messages sent between nodes are encrypted with the receiver's public key. Any unencrypted messages are ignored.
|
|
106
118
|
|
|
107
119
|
### pubsub-adapter.js
|
|
108
120
|
|
|
109
|
-
The pubsub adapter can publish a message to a pubsub channel, and route incoming messages to an appropriate handler. There are (public) coordination channels that many peers subscribe to, and messages are published unencrypted.
|
|
121
|
+
The pubsub adapter can publish a message to a pubsub channel, and route incoming messages to an appropriate handler. There are (public) coordination channels that many peers subscribe to, and messages are published unencrypted. Private messages between peers are sent as encrypted payloads published to the recipient's private pubsub channel.
|
|
122
|
+
|
|
123
|
+
### gist.js
|
|
110
124
|
|
|
111
|
-
|
|
125
|
+
The Gist adapter interfaces with the GitHub Gist API and the PSF bootstrap server. It is used to download a maintained list of Circuit Relays operated by members of the PSF, providing an up-to-date set of relay nodes that the library can connect to at startup.
|
|
112
126
|
|
|
113
127
|
### schema.js
|
|
114
128
|
|
|
115
|
-
The schema library
|
|
129
|
+
The schema library contains formatted JSON objects that are used to generate standardized messages for communication between peers. The schema.js library is instantiated at startup and appended to the thisNode Entity.
|
package/lib/create-helia-node.js
CHANGED
|
@@ -153,9 +153,9 @@ class CreateHeliaNode {
|
|
|
153
153
|
services.relay = circuitRelayServer({
|
|
154
154
|
hopTimeout: 30 * 1000,
|
|
155
155
|
reservations: {
|
|
156
|
-
maxReservations:
|
|
156
|
+
maxReservations: 45,
|
|
157
157
|
reservationClearInterval: 300 * 1000,
|
|
158
|
-
applyDefaultLimit:
|
|
158
|
+
applyDefaultLimit: false,
|
|
159
159
|
defaultDurationLimit: 2 * 60 * 1000,
|
|
160
160
|
defaultDataLimit: BigInt(2 << 7)
|
|
161
161
|
},
|
package/package.json
CHANGED