Rename getStatusFleetNodes

To make it more generic to allow retrieval of bootstrap nodes from
other sources.
This commit is contained in:
Franck Royer 2021-08-09 16:25:10 +10:00
parent 729c81430c
commit c3855112d7
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
13 changed files with 110 additions and 71 deletions

View File

@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Changed
- Renamed `discover.getStatusFleetNodes` to `discovery.getBootstrapNodes` and make it more generic to allow retrieval of bootstrap nodes from other sources.
### Removed
- Examples (cli-chat): The focus of this library is Web environment;
Several examples now cover usage of Waku Relay and Waku Store making cli-chat example obsolete;

View File

@ -48,12 +48,12 @@ waku.addPeerToAddressBook(
);
```
You can also use `getStatusFleetNodes` to connect to nodes run by Status:
You can also use `getBootstrapNodes` to connect to Waku bootstrap nodes:
```ts
import { getStatusFleetNodes } from 'js-waku';
import { getBootstrapNodes } from 'js-waku';
getStatusFleetNodes().then((nodes) => {
getBootstrapNodes().then((nodes) => {
nodes.forEach((addr) => {
waku.dial(addr);
});

View File

@ -1,5 +1,5 @@
import { Dispatch, SetStateAction } from 'react';
import { getStatusFleetNodes, Waku, WakuMessage } from 'js-waku';
import { getBootstrapNodes, Waku, WakuMessage } from 'js-waku';
import { DirectMessage, PublicKeyMessage } from './messaging/wire';
import { validatePublicKeyMessage } from './crypto';
import { Message } from './messaging/Messages';
@ -12,7 +12,7 @@ export async function initWaku(): Promise<Waku> {
const waku = await Waku.create({});
// Dial all nodes it can find
getStatusFleetNodes().then((nodes) => {
getBootstrapNodes().then((nodes) => {
nodes.forEach((addr) => {
waku.dial(addr);
});

View File

@ -1,5 +1,5 @@
import { Dispatch, SetStateAction } from 'react';
import { getStatusFleetNodes, Waku, WakuMessage } from 'js-waku';
import { getBootstrapNodes, Waku, WakuMessage } from 'js-waku';
import { DirectMessage, PublicKeyMessage } from './messaging/wire';
import { validatePublicKeyMessage } from './crypto';
import { Message } from './messaging/Messages';
@ -14,7 +14,7 @@ export async function initWaku(): Promise<Waku> {
const waku = await Waku.create({});
// Dial all nodes it can find
getStatusFleetNodes().then((nodes) => {
getBootstrapNodes().then((nodes) => {
nodes.forEach((addr) => {
waku.dial(addr);
});

View File

@ -1,5 +1,5 @@
import './App.css';
import { getStatusFleetNodes, Waku, WakuMessage } from 'js-waku';
import { getBootstrapNodes, Waku, WakuMessage } from 'js-waku';
import * as React from 'react';
import protons from 'protons';
@ -96,8 +96,12 @@ function App() {
export default App;
async function bootstrapWaku(waku) {
const nodes = await getStatusFleetNodes();
await Promise.all(nodes.map((addr) => waku.dial(addr)));
try {
const nodes = await getBootstrapNodes();
await Promise.all(nodes.map((addr) => waku.dial(addr)));
} catch (e) {
console.error('Failed to bootstrap to Waku network');
}
}
async function sendMessage(message, timestamp, waku) {

View File

@ -1,5 +1,5 @@
import './App.css';
import { getStatusFleetNodes, StoreCodec, Waku } from 'js-waku';
import { getBootstrapNodes, StoreCodec, Waku } from 'js-waku';
import * as React from 'react';
import protons from 'protons';
@ -101,8 +101,12 @@ function App() {
export default App;
async function bootstrapWaku(waku) {
const nodes = await getStatusFleetNodes();
await Promise.all(nodes.map((addr) => waku.dial(addr)));
try {
const nodes = await getBootstrapNodes();
await Promise.all(nodes.map((addr) => waku.dial(addr)));
} catch (e) {
console.error('Failed to bootstrap to Waku network');
}
}
function decodeMessage(wakuMessage) {

View File

@ -2,8 +2,7 @@ import { useEffect, useReducer, useState } from 'react';
import './App.css';
import {
Direction,
Environment,
getStatusFleetNodes,
getBootstrapNodes,
StoreCodec,
Waku,
WakuMessage,
@ -83,10 +82,8 @@ export default function App() {
const persistedNick = window.localStorage.getItem('nick');
return persistedNick !== null ? persistedNick : generate();
});
const [
historicalMessagesRetrieved,
setHistoricalMessagesRetrieved,
] = useState(false);
const [historicalMessagesRetrieved, setHistoricalMessagesRetrieved] =
useState(false);
useEffect(() => {
localStorage.setItem('nick', nick);
@ -186,7 +183,7 @@ async function initWaku(setter: (waku: Waku) => void) {
setter(waku);
const nodes = await getStatusFleetNodes(selectFleetEnv());
const nodes = await getBootstrapNodes(selectFleetEnv());
await Promise.all(
nodes.map((addr) => {
return waku.dial(addr);
@ -200,9 +197,9 @@ async function initWaku(setter: (waku: Waku) => void) {
function selectFleetEnv() {
// Works with react-scripts
if (process?.env?.NODE_ENV === 'development') {
return Environment.Test;
return ['fleets', 'wakuv2.test', 'waku-websocket'];
} else {
return Environment.Prod;
return ['fleets', 'wakuv2.prod', 'waku-websocket'];
}
}

View File

@ -82,16 +82,18 @@ function App() {
# Connect to Other Peers
The Waku instance needs to connect to other peers to communicate with the network.
First, create `bootstrapWaku` to connect to the Status fleet:
First, create `bootstrapWaku` to connect to Waku bootstrap nodes (hosted by Status):
```js
import { getStatusFleetNodes } from 'js-waku';
import { getBootstrapNodes } from 'js-waku';
async function bootstrapWaku(waku) {
// Retrieve node addresses from https://fleets.status.im/
const nodes = await getStatusFleetNodes();
// Connect to the nodes
await Promise.all(nodes.map((addr) => waku.dial(addr)));
try {
const nodes = await getBootstrapNodes();
await Promise.all(nodes.map((addr) => waku.dial(addr)));
} catch (e) {
console.error('Failed to bootstrap to Waku network');
}
}
```

View File

@ -34,9 +34,10 @@ You are free to choose any method to bootstrap and DappConnect will ship with ne
For now, the easiest way is to connect to Status' Waku fleet:
```js
import { getStatusFleetNodes } from 'js-waku';
const nodes = await getStatusFleetNodes();
await Promise.all(nodes.map((addr) => waku.dial(addr)));
import { getBootstrapNodes } from 'js-waku';
const nodes = await getBootstrapNodes();
await Promise.all(nodes.map((addr) => waku.dial(addr)));
```
# Receive messages
@ -177,7 +178,7 @@ Feel free to check out other [guides](menu.md) or [examples](/examples/examples.
Here is the final code:
```js
import { getStatusFleetNodes, Waku, WakuMessage } from 'js-waku';
import { getBootstrapNodes, Waku, WakuMessage } from 'js-waku';
import protons from 'protons';
const proto = protons(`
@ -189,7 +190,7 @@ message SimpleChatMessage {
const wakuNode = await Waku.create();
const nodes = await getStatusFleetNodes();
const nodes = await getBootstrapNodes();
await Promise.all(nodes.map((addr) => waku.dial(addr)));
const processIncomingMessage = (wakuMessage) => {

View File

@ -46,12 +46,17 @@ const wakuNode = await Waku.create();
The Waku instance needs to connect to other peers to communicate with the network.
You are free to choose other methods to bootstrap and DappConnect will ship with new bootstrap mechanisms in the future.
For now, the easiest way is to connect to Status' Waku fleet:
For now, the easiest way is to connect to Waku bootstrap nodes:
```js
import { getStatusFleetNodes } from 'js-waku';
const nodes = await getStatusFleetNodes();
await Promise.all(nodes.map((addr) => waku.dial(addr)));
import { getBootstrapNodes } from 'js-waku';
try {
const nodes = await getBootstrapNodes();
await Promise.all(nodes.map((addr) => waku.dial(addr)));
} catch (e) {
console.error('Failed to bootstrap to Waku network');
}
```
# Use Protobuf

View File

@ -1,4 +1,4 @@
export { getStatusFleetNodes, Environment, Protocol } from './lib/discover';
export { getBootstrapNodes } from './lib/discovery';
export * as utils from './lib/utils';

View File

@ -1,33 +0,0 @@
/**
* Returns multiaddrs (inc. ip) of nim-waku nodes ran by Status.
* Used as a temporary discovery helper until more parties run their own nodes.
*/
import axios from 'axios';
export enum Protocol {
websocket = 'websocket',
tcp = 'tcp',
}
export enum Environment {
Test = 'test',
Prod = 'prod',
}
export async function getStatusFleetNodes(
env: Environment = Environment.Prod,
protocol: Protocol = Protocol.websocket
): Promise<string[]> {
const res = await axios.get('https://fleets.status.im/', {
headers: { 'Content-Type': 'application/json' },
});
const wakuFleet = res.data.fleets[`wakuv2.${env}`];
switch (protocol) {
case Protocol.tcp:
return Object.values(wakuFleet['waku']);
default:
return Object.values(wakuFleet['waku-websocket']);
}
}

56
src/lib/discovery.ts Normal file
View File

@ -0,0 +1,56 @@
import axios from 'axios';
import debug from 'debug';
const dbg = debug('waku:discovery');
/**
* GET list of nodes from remote HTTP host.
*
* @param path The property path to access the node list. The result should be
* a string, a string array or an object. If the result is an object then the
* values of the objects are used as multiaddresses.
* @param url Remote host containing bootstrap peers in JSON format.
*
* @returns An array of multiaddresses.
* @throws If the remote host is unreachable or the response cannot be parsed
* according to the passed _path_.
*/
export async function getBootstrapNodes(
path: string[] = ['fleets', 'wakuv2.prod', 'waku-websocket'],
url = 'https://fleets.status.im/'
): Promise<string[]> {
const res = await axios.get(url, {
headers: { 'Content-Type': 'application/json' },
});
let nodes = res.data;
for (const prop of path) {
if (nodes[prop] === undefined) {
dbg(
`Failed to retrieve bootstrap nodes: ${prop} does not exist on `,
nodes
);
throw `Failed to retrieve bootstrap nodes: ${prop} does not exist on ${JSON.stringify(
nodes
)}`;
}
nodes = nodes[prop];
}
if (Array.isArray(nodes)) {
return nodes;
}
if (typeof nodes === 'string') {
return [nodes];
}
if (typeof nodes === 'object') {
return Object.values(nodes);
}
throw `Failed to retrieve bootstrap nodes: response format is not supported: ${JSON.stringify(
nodes
)}`;
}