@leofcoin/peernet 1.1.57 → 1.1.58
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/.esdoc.json +10 -10
- package/.eslintrc.json +24 -24
- package/.gitattributes +2 -2
- package/.travis.yml +27 -27
- package/BREAKING_CHANGES.md +34 -34
- package/LICENSE +21 -21
- package/README.md +72 -72
- package/deploy.js +8 -8
- package/exports/browser/{index-329e0324.js → index-8868bdd8.js} +1 -1
- package/exports/browser/{messages-000b7f84.js → messages-eb6e5c71.js} +174 -174
- package/exports/browser/{peernet-bfbe6fff.js → peernet-87ea02a4.js} +2005 -1915
- package/exports/browser/peernet.d.ts +13 -11
- package/exports/browser/peernet.js +1 -1
- package/exports/{messages-dc960cb3.js → messages-b9a32987.js} +173 -173
- package/exports/peernet.js +288 -246
- package/exports/src/prompts/password.js +3 -3
- package/exports/store.js +7 -8
- package/exports/types/peernet.d.ts +13 -11
- package/index.html +19 -19
- package/package.json +70 -70
- package/rollup.config.js +76 -69
- package/src/dht/dht.ts +141 -141
- package/src/discovery/peer-discovery.js +75 -75
- package/src/errors/errors.js +12 -12
- package/src/handlers/data.js +11 -11
- package/src/handlers/message.js +34 -34
- package/src/identity.ts +101 -101
- package/src/messages/chat.js +14 -14
- package/src/messages/data-response.js +14 -14
- package/src/messages/data.js +18 -18
- package/src/messages/dht-response.js +14 -14
- package/src/messages/dht.js +22 -22
- package/src/messages/file-link.js +18 -18
- package/src/messages/file.js +18 -18
- package/src/messages/peer-response.js +14 -14
- package/src/messages/peer.js +13 -13
- package/src/messages/peernet.js +14 -14
- package/src/messages/ps.js +13 -13
- package/src/messages/request.js +14 -14
- package/src/messages/response.js +14 -14
- package/src/messages.js +13 -13
- package/src/peer-info.js +9 -9
- package/src/peernet.ts +848 -776
- package/src/prompts/password/node.js +5 -5
- package/src/proto/chat-message.proto.js +6 -6
- package/src/proto/data-response.proto.js +4 -4
- package/src/proto/data.proto.js +4 -4
- package/src/proto/dht-response.proto.js +4 -4
- package/src/proto/dht.proto.js +4 -4
- package/src/proto/file-link.proto.js +5 -5
- package/src/proto/file.proto.js +5 -5
- package/src/proto/peer-response.proto.js +3 -3
- package/src/proto/peer.proto.js +3 -3
- package/src/proto/peernet.proto.js +7 -7
- package/src/proto/ps.proto.js +4 -4
- package/src/proto/request.proto.js +4 -4
- package/src/proto/response.proto.js +3 -3
- package/src/types.ts +27 -27
- package/src/utils/utils.js +78 -78
- package/test/client.js +14 -14
- package/test/codec.js +56 -56
- package/test/hash.js +13 -13
- package/test/index.js +3 -3
- package/test/lastBlock.js +7 -7
- package/test/messages.js +26 -26
- package/test/peernet.js +17 -17
- package/test.js +64 -64
- package/test2.js +9 -9
- package/test3.js +15 -15
- package/test4.js +7 -7
- package/tsconfig.json +12 -12
package/exports/peernet.js
CHANGED
|
@@ -9,140 +9,140 @@ import { decrypt } from '@leofcoin/identity-utils';
|
|
|
9
9
|
import QrScanner from 'qr-scanner';
|
|
10
10
|
import qrcode from 'qrcode';
|
|
11
11
|
|
|
12
|
-
const BufferToUint8Array = data => {
|
|
13
|
-
if (data.type === 'Buffer') {
|
|
14
|
-
data = new Uint8Array(data.data);
|
|
15
|
-
}
|
|
16
|
-
return data
|
|
12
|
+
const BufferToUint8Array = data => {
|
|
13
|
+
if (data.type === 'Buffer') {
|
|
14
|
+
data = new Uint8Array(data.data);
|
|
15
|
+
}
|
|
16
|
+
return data
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const protoFor = (message) => {
|
|
20
|
+
const codec = new Codec(message);
|
|
21
|
+
if (!codec.name) throw new Error('proto not found')
|
|
22
|
+
const Proto = globalThis.peernet.protos[codec.name];
|
|
23
|
+
if (!Proto) throw (new Error(`No proto defined for ${codec.name}`))
|
|
24
|
+
return new Proto(message)
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* wether or not a peernet daemon is active
|
|
29
|
+
* @return {Boolean}
|
|
30
|
+
*/
|
|
31
|
+
const hasDaemon = async () => {
|
|
32
|
+
try {
|
|
33
|
+
let response = await fetch('http://127.0.0.1:1000/api/version');
|
|
34
|
+
response = await response.json();
|
|
35
|
+
return Boolean(response.client === '@peernet/api/http')
|
|
36
|
+
} catch (e) {
|
|
37
|
+
return false
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const https = () => {
|
|
42
|
+
if (!globalThis.location) return false;
|
|
43
|
+
return Boolean(globalThis.location.protocol === 'https:')
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get current environment
|
|
48
|
+
* @return {String} current environment [node, electron, browser]
|
|
49
|
+
*/
|
|
50
|
+
const environment = () => {
|
|
51
|
+
const _navigator = globalThis.navigator;
|
|
52
|
+
if (!_navigator) {
|
|
53
|
+
return 'node'
|
|
54
|
+
} else if (_navigator && /electron/i.test(_navigator.userAgent)) {
|
|
55
|
+
return 'electron'
|
|
56
|
+
} else {
|
|
57
|
+
return 'browser'
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* * Get current environment
|
|
63
|
+
* @return {Object} result
|
|
64
|
+
* @property {Boolean} reult.daemon whether or not daemon is running
|
|
65
|
+
* @property {Boolean} reult.environment Current environment
|
|
66
|
+
*/
|
|
67
|
+
const target = async () => {
|
|
68
|
+
let daemon = false;
|
|
69
|
+
if (!https()) daemon = await hasDaemon();
|
|
70
|
+
|
|
71
|
+
return {daemon, environment: environment()}
|
|
17
72
|
};
|
|
18
73
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (id) return id
|
|
92
|
-
const data = await new peernet.protos['peernet-peer']({id: this.id});
|
|
93
|
-
const node = await peernet.prepareMessage(peer.id, data.encoded);
|
|
94
|
-
|
|
95
|
-
let response = await peer.request(node.encoded);
|
|
96
|
-
response = await protoFor(response);
|
|
97
|
-
response = await new peernet.protos['peernet-peer-response'](response.decoded.data);
|
|
98
|
-
|
|
99
|
-
id = response.decoded.id;
|
|
100
|
-
if (id === this.id) return;
|
|
101
|
-
|
|
102
|
-
if (!peernet.peerMap.has(id)) peernet.peerMap.set(id, [peer.id]);
|
|
103
|
-
else {
|
|
104
|
-
const connections = peernet.peerMap.get(id);
|
|
105
|
-
if (connections.indexOf(peer.id) === -1) {
|
|
106
|
-
connections.push(peer.id);
|
|
107
|
-
peernet.peerMap.set(peer.id, connections);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
return id
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
async discoverHandler(message, peer) {
|
|
114
|
-
const {id, proto} = message;
|
|
115
|
-
// if (typeof message.data === 'string') message.data = Buffer.from(message.data)
|
|
116
|
-
if (proto.name === 'peernet-peer') {
|
|
117
|
-
const from = proto.decoded.id;
|
|
118
|
-
if (from === this.id) return;
|
|
119
|
-
|
|
120
|
-
if (!peernet.peerMap.has(from)) peernet.peerMap.set(from, [peer.id]);
|
|
121
|
-
else {
|
|
122
|
-
const connections = peernet.peerMap.get(from);
|
|
123
|
-
if (connections.indexOf(peer.id) === -1) {
|
|
124
|
-
connections.push(peer.id);
|
|
125
|
-
peernet.peerMap.set(from, connections);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
const data = await new peernet.protos['peernet-peer-response']({id: this.id});
|
|
129
|
-
const node = await peernet.prepareMessage(from, data.encoded);
|
|
130
|
-
|
|
131
|
-
peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
|
|
132
|
-
} else if (proto.name === 'peernet-peer-response') {
|
|
133
|
-
const from = proto.decoded.id;
|
|
134
|
-
if (from === this.id) return;
|
|
135
|
-
|
|
136
|
-
if (!peernet.peerMap.has(from)) peernet.peerMap.set(from, [peer.id]);
|
|
137
|
-
else {
|
|
138
|
-
const connections = peernet.peerMap.get(from);
|
|
139
|
-
if (connections.indexOf(peer.id) === -1) {
|
|
140
|
-
connections.push(peer.id);
|
|
141
|
-
peernet.peerMap.set(from, connections);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
74
|
+
class PeerDiscovery {
|
|
75
|
+
constructor(id) {
|
|
76
|
+
this.id = id;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
_getPeerId(id) {
|
|
80
|
+
if (!peernet.peerMap || peernet.peerMap && peernet.peerMap.size === 0) return false
|
|
81
|
+
|
|
82
|
+
for (const entry of [...peernet.peerMap.entries()]) {
|
|
83
|
+
for (const _id of entry[1]) {
|
|
84
|
+
if (_id === id) return entry[0]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async discover(peer) {
|
|
90
|
+
let id = this._getPeerId(peer.id);
|
|
91
|
+
if (id) return id
|
|
92
|
+
const data = await new peernet.protos['peernet-peer']({id: this.id});
|
|
93
|
+
const node = await peernet.prepareMessage(peer.id, data.encoded);
|
|
94
|
+
|
|
95
|
+
let response = await peer.request(node.encoded);
|
|
96
|
+
response = await protoFor(response);
|
|
97
|
+
response = await new peernet.protos['peernet-peer-response'](response.decoded.data);
|
|
98
|
+
|
|
99
|
+
id = response.decoded.id;
|
|
100
|
+
if (id === this.id) return;
|
|
101
|
+
|
|
102
|
+
if (!peernet.peerMap.has(id)) peernet.peerMap.set(id, [peer.id]);
|
|
103
|
+
else {
|
|
104
|
+
const connections = peernet.peerMap.get(id);
|
|
105
|
+
if (connections.indexOf(peer.id) === -1) {
|
|
106
|
+
connections.push(peer.id);
|
|
107
|
+
peernet.peerMap.set(peer.id, connections);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return id
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async discoverHandler(message, peer) {
|
|
114
|
+
const {id, proto} = message;
|
|
115
|
+
// if (typeof message.data === 'string') message.data = Buffer.from(message.data)
|
|
116
|
+
if (proto.name === 'peernet-peer') {
|
|
117
|
+
const from = proto.decoded.id;
|
|
118
|
+
if (from === this.id) return;
|
|
119
|
+
|
|
120
|
+
if (!peernet.peerMap.has(from)) peernet.peerMap.set(from, [peer.id]);
|
|
121
|
+
else {
|
|
122
|
+
const connections = peernet.peerMap.get(from);
|
|
123
|
+
if (connections.indexOf(peer.id) === -1) {
|
|
124
|
+
connections.push(peer.id);
|
|
125
|
+
peernet.peerMap.set(from, connections);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const data = await new peernet.protos['peernet-peer-response']({id: this.id});
|
|
129
|
+
const node = await peernet.prepareMessage(from, data.encoded);
|
|
130
|
+
|
|
131
|
+
peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})));
|
|
132
|
+
} else if (proto.name === 'peernet-peer-response') {
|
|
133
|
+
const from = proto.decoded.id;
|
|
134
|
+
if (from === this.id) return;
|
|
135
|
+
|
|
136
|
+
if (!peernet.peerMap.has(from)) peernet.peerMap.set(from, [peer.id]);
|
|
137
|
+
else {
|
|
138
|
+
const connections = peernet.peerMap.get(from);
|
|
139
|
+
if (connections.indexOf(peer.id) === -1) {
|
|
140
|
+
connections.push(peer.id);
|
|
141
|
+
peernet.peerMap.set(from, connections);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
/**
|
|
@@ -252,56 +252,56 @@ class DhtEarth {
|
|
|
252
252
|
}
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
class MessageHandler {
|
|
256
|
-
constructor(network) {
|
|
257
|
-
this.network = network;
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* hash and sign message
|
|
261
|
-
*
|
|
262
|
-
* @param {object} message
|
|
263
|
-
* @param {Buffer} message.from peer id
|
|
264
|
-
* @param {Buffer} message.to peer id
|
|
265
|
-
* @param {string} message.data Peernet message
|
|
266
|
-
* (PeernetMessage excluded) encoded as a string
|
|
267
|
-
* @return message
|
|
268
|
-
*/
|
|
269
|
-
async hashAndSignMessage(message) {
|
|
270
|
-
const hash = await message.peernetHash;
|
|
271
|
-
message.decoded.signature = globalThis.identity.sign(hash.buffer);
|
|
272
|
-
return message
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* @param {String} from - peer id
|
|
277
|
-
* @param {String} to - peer id
|
|
278
|
-
* @param {String|PeernetMessage} data - data encoded message string
|
|
279
|
-
* or the messageNode itself
|
|
280
|
-
*/
|
|
281
|
-
async prepareMessage(message) {
|
|
282
|
-
if (message.keys.includes('signature')) {
|
|
283
|
-
message = await this.hashAndSignMessage(message);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
return message
|
|
287
|
-
}
|
|
255
|
+
class MessageHandler {
|
|
256
|
+
constructor(network) {
|
|
257
|
+
this.network = network;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* hash and sign message
|
|
261
|
+
*
|
|
262
|
+
* @param {object} message
|
|
263
|
+
* @param {Buffer} message.from peer id
|
|
264
|
+
* @param {Buffer} message.to peer id
|
|
265
|
+
* @param {string} message.data Peernet message
|
|
266
|
+
* (PeernetMessage excluded) encoded as a string
|
|
267
|
+
* @return message
|
|
268
|
+
*/
|
|
269
|
+
async hashAndSignMessage(message) {
|
|
270
|
+
const hash = await message.peernetHash;
|
|
271
|
+
message.decoded.signature = globalThis.identity.sign(hash.buffer);
|
|
272
|
+
return message
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* @param {String} from - peer id
|
|
277
|
+
* @param {String} to - peer id
|
|
278
|
+
* @param {String|PeernetMessage} data - data encoded message string
|
|
279
|
+
* or the messageNode itself
|
|
280
|
+
*/
|
|
281
|
+
async prepareMessage(message) {
|
|
282
|
+
if (message.keys.includes('signature')) {
|
|
283
|
+
message = await this.hashAndSignMessage(message);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return message
|
|
287
|
+
}
|
|
288
288
|
}
|
|
289
289
|
|
|
290
|
-
const dataHandler = async message => {
|
|
291
|
-
if (!message) return
|
|
292
|
-
|
|
293
|
-
const {data, id, from, peer} = message;
|
|
294
|
-
const proto = await protoFor(data);
|
|
295
|
-
peernet._protoHandler({id, proto}, peernet.connections[from] || peer, from);
|
|
296
|
-
};
|
|
297
|
-
|
|
298
|
-
const dhtError = (proto) => {
|
|
299
|
-
const text = `Received proto ${proto.name} expected peernet-dht-response`;
|
|
300
|
-
return new Error(`Routing error: ${text}`)
|
|
290
|
+
const dataHandler = async message => {
|
|
291
|
+
if (!message) return
|
|
292
|
+
|
|
293
|
+
const {data, id, from, peer} = message;
|
|
294
|
+
const proto = await protoFor(data);
|
|
295
|
+
peernet._protoHandler({id, proto}, peernet.connections[from] || peer, from);
|
|
301
296
|
};
|
|
302
297
|
|
|
303
|
-
const
|
|
304
|
-
|
|
298
|
+
const dhtError = (proto) => {
|
|
299
|
+
const text = `Received proto ${proto.name} expected peernet-dht-response`;
|
|
300
|
+
return new Error(`Routing error: ${text}`)
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
const nothingFoundError = (hash) => {
|
|
304
|
+
return new Error(`nothing found for ${hash}`)
|
|
305
305
|
};
|
|
306
306
|
|
|
307
307
|
class Identity {
|
|
@@ -439,17 +439,20 @@ class Peernet {
|
|
|
439
439
|
/**
|
|
440
440
|
* @property {String} network - current network
|
|
441
441
|
*/
|
|
442
|
-
this.network = options.network ||
|
|
442
|
+
this.network = options.network || "leofcoin";
|
|
443
443
|
this.autoStart = options.autoStart === undefined ? true : options.autoStart;
|
|
444
444
|
this.stars = options.stars;
|
|
445
|
-
const parts = this.network.split(
|
|
446
|
-
this.networkVersion =
|
|
445
|
+
const parts = this.network.split(":");
|
|
446
|
+
this.networkVersion =
|
|
447
|
+
options.networkVersion || parts.length > 1 ? parts[1] : "mainnet";
|
|
447
448
|
if (!options.storePrefix)
|
|
448
|
-
options.storePrefix =
|
|
449
|
+
options.storePrefix = "lfc";
|
|
449
450
|
if (!options.port)
|
|
450
451
|
options.port = 2000;
|
|
451
452
|
if (!options.root) {
|
|
452
|
-
parts[1]
|
|
453
|
+
parts[1]
|
|
454
|
+
? (options.root = `.${parts[0]}/${parts[1]}`)
|
|
455
|
+
: (options.root = `.${this.network}`);
|
|
453
456
|
}
|
|
454
457
|
globalThis.peernet = this;
|
|
455
458
|
this.bw = {
|
|
@@ -469,7 +472,15 @@ class Peernet {
|
|
|
469
472
|
return this.identity.accounts;
|
|
470
473
|
}
|
|
471
474
|
get defaultStores() {
|
|
472
|
-
return [
|
|
475
|
+
return [
|
|
476
|
+
"account",
|
|
477
|
+
"wallet",
|
|
478
|
+
"block",
|
|
479
|
+
"transaction",
|
|
480
|
+
"chain",
|
|
481
|
+
"data",
|
|
482
|
+
"message",
|
|
483
|
+
];
|
|
473
484
|
}
|
|
474
485
|
selectAccount(account) {
|
|
475
486
|
return this.identity.selectAccount(account);
|
|
@@ -482,11 +493,16 @@ class Peernet {
|
|
|
482
493
|
return utils.addCodec(codec);
|
|
483
494
|
}
|
|
484
495
|
async addStore(name, prefix, root, isPrivate = true) {
|
|
485
|
-
if (name ===
|
|
486
|
-
name ===
|
|
496
|
+
if (name === "block" ||
|
|
497
|
+
name === "transaction" ||
|
|
498
|
+
name === "chain" ||
|
|
499
|
+
name === "data" ||
|
|
500
|
+
name === "message")
|
|
487
501
|
isPrivate = false;
|
|
488
502
|
let Storage;
|
|
489
|
-
this.hasDaemon
|
|
503
|
+
this.hasDaemon
|
|
504
|
+
? (Storage = LeofcoinStorageClient)
|
|
505
|
+
: (Storage = LeofcoinStorage);
|
|
490
506
|
if (!globalThis[`${name}Store`]) {
|
|
491
507
|
globalThis[`${name}Store`] = new Storage(name, root);
|
|
492
508
|
await globalThis[`${name}Store`].init();
|
|
@@ -532,9 +548,9 @@ class Peernet {
|
|
|
532
548
|
async _init(options, password) {
|
|
533
549
|
this.storePrefix = options.storePrefix;
|
|
534
550
|
this.root = options.root;
|
|
535
|
-
const { RequestMessage, ResponseMessage, PeerMessage, PeerMessageResponse, PeernetMessage, DHTMessage, DHTMessageResponse, DataMessage, DataMessageResponse, PsMessage, ChatMessage, PeernetFile
|
|
551
|
+
const { RequestMessage, ResponseMessage, PeerMessage, PeerMessageResponse, PeernetMessage, DHTMessage, DHTMessageResponse, DataMessage, DataMessageResponse, PsMessage, ChatMessage, PeernetFile,
|
|
536
552
|
// FolderMessageResponse
|
|
537
|
-
} = await import(/* webpackChunkName: "messages" */ './messages-
|
|
553
|
+
} = await import(/* webpackChunkName: "messages" */ './messages-b9a32987.js');
|
|
538
554
|
/**
|
|
539
555
|
* proto Object containing protos
|
|
540
556
|
* @type {Object}
|
|
@@ -545,18 +561,18 @@ class Peernet {
|
|
|
545
561
|
* @property {DataMessageResponse} protos[peernet-data-response] messageNode
|
|
546
562
|
*/
|
|
547
563
|
globalThis.peernet.protos = {
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
564
|
+
"peernet-request": RequestMessage,
|
|
565
|
+
"peernet-response": ResponseMessage,
|
|
566
|
+
"peernet-peer": PeerMessage,
|
|
567
|
+
"peernet-peer-response": PeerMessageResponse,
|
|
568
|
+
"peernet-message": PeernetMessage,
|
|
569
|
+
"peernet-dht": DHTMessage,
|
|
570
|
+
"peernet-dht-response": DHTMessageResponse,
|
|
571
|
+
"peernet-data": DataMessage,
|
|
572
|
+
"peernet-data-response": DataMessageResponse,
|
|
573
|
+
"peernet-ps": PsMessage,
|
|
574
|
+
"chat-message": ChatMessage,
|
|
575
|
+
"peernet-file": PeernetFile,
|
|
560
576
|
};
|
|
561
577
|
this._messageHandler = new MessageHandler(this.network);
|
|
562
578
|
const { daemon, environment } = await target();
|
|
@@ -568,38 +584,44 @@ class Peernet {
|
|
|
568
584
|
await this.identity.load(password);
|
|
569
585
|
this._peerHandler = new PeerDiscovery(this.id);
|
|
570
586
|
this.peerId = this.id;
|
|
571
|
-
this.addRequestHandler(
|
|
572
|
-
return new peernet.protos[
|
|
587
|
+
this.addRequestHandler("handshake", () => {
|
|
588
|
+
return new peernet.protos["peernet-response"]({
|
|
589
|
+
response: { peerId: this.id },
|
|
590
|
+
});
|
|
573
591
|
});
|
|
574
|
-
pubsub.subscribe(
|
|
592
|
+
pubsub.subscribe("peer:discovered", async (peer) => {
|
|
575
593
|
// console.log(peer);
|
|
576
|
-
if (this.requestProtos[
|
|
577
|
-
let data = await new globalThis.peernet.protos[
|
|
594
|
+
if (this.requestProtos["version"]) {
|
|
595
|
+
let data = await new globalThis.peernet.protos["peernet-request"]({
|
|
596
|
+
request: "version",
|
|
597
|
+
});
|
|
578
598
|
let node = await globalThis.peernet.prepareMessage(data);
|
|
579
599
|
let response = await peer.request(node.encoded);
|
|
580
|
-
response = await new globalThis.peernet.protos[
|
|
600
|
+
response = await new globalThis.peernet.protos["peernet-response"](new Uint8Array(Object.values(response)));
|
|
581
601
|
peer.version = response.decoded.response.version;
|
|
582
602
|
}
|
|
583
|
-
let data = await new globalThis.peernet.protos[
|
|
603
|
+
let data = await new globalThis.peernet.protos["peernet-request"]({
|
|
604
|
+
request: "handshake",
|
|
605
|
+
});
|
|
584
606
|
let node = await globalThis.peernet.prepareMessage(data);
|
|
585
607
|
let response = await peer.request(node.encoded);
|
|
586
|
-
response = await new globalThis.peernet.protos[
|
|
608
|
+
response = await new globalThis.peernet.protos["peernet-response"](new Uint8Array(Object.values(response)));
|
|
587
609
|
// todo: response.decoded should be the response and not response.peerId
|
|
588
610
|
this.#connections[response.decoded.response.peerId] = peer;
|
|
589
|
-
pubsub.publish(
|
|
611
|
+
pubsub.publish("peer:connected", peer);
|
|
590
612
|
// todo: cleanup discovered
|
|
591
613
|
});
|
|
592
|
-
pubsub.subscribe(
|
|
614
|
+
pubsub.subscribe("peer:left", this.#peerLeft.bind(this));
|
|
593
615
|
/**
|
|
594
616
|
* converts data -> message -> proto
|
|
595
617
|
* @see DataHandler
|
|
596
618
|
*/
|
|
597
|
-
pubsub.subscribe(
|
|
619
|
+
pubsub.subscribe("peer:data", dataHandler);
|
|
598
620
|
if (globalThis.navigator) {
|
|
599
|
-
globalThis.addEventListener(
|
|
621
|
+
globalThis.addEventListener("beforeunload", async () => this.client.destroy());
|
|
600
622
|
}
|
|
601
623
|
else {
|
|
602
|
-
process.on(
|
|
624
|
+
process.on("SIGTERM", async () => {
|
|
603
625
|
process.stdin.resume();
|
|
604
626
|
try {
|
|
605
627
|
await this.client.destroy();
|
|
@@ -630,7 +652,9 @@ class Peernet {
|
|
|
630
652
|
}
|
|
631
653
|
#peerLeft(peer) {
|
|
632
654
|
for (const [id, _peer] of Object.entries(this.#connections)) {
|
|
633
|
-
if (_peer.id === peer.id &&
|
|
655
|
+
if (_peer.id === peer.id &&
|
|
656
|
+
this.#connections[id] &&
|
|
657
|
+
!this.#connections[id].connected) {
|
|
634
658
|
delete this.#connections[id];
|
|
635
659
|
this.removePeer(_peer);
|
|
636
660
|
}
|
|
@@ -657,18 +681,26 @@ class Peernet {
|
|
|
657
681
|
else {
|
|
658
682
|
has = await this.has(hash);
|
|
659
683
|
}
|
|
660
|
-
const data = await new globalThis.peernet.protos[
|
|
684
|
+
const data = await new globalThis.peernet.protos["peernet-dht-response"]({
|
|
685
|
+
hash,
|
|
686
|
+
has,
|
|
687
|
+
});
|
|
661
688
|
const node = await this.prepareMessage(data);
|
|
662
689
|
this.sendMessage(peer, id, node.encoded);
|
|
663
690
|
}
|
|
664
691
|
async handleData(peer, id, proto) {
|
|
665
692
|
let { hash, store } = proto.decoded;
|
|
666
693
|
let data;
|
|
667
|
-
store =
|
|
694
|
+
store =
|
|
695
|
+
globalThis[`${store}Store`] ||
|
|
696
|
+
(await this.whichStore([...this.stores], hash));
|
|
668
697
|
if (store && !store.private) {
|
|
669
698
|
data = await store.get(hash);
|
|
670
699
|
if (data) {
|
|
671
|
-
data = await new globalThis.peernet.protos[
|
|
700
|
+
data = await new globalThis.peernet.protos["peernet-data-response"]({
|
|
701
|
+
hash,
|
|
702
|
+
data,
|
|
703
|
+
});
|
|
672
704
|
const node = await this.prepareMessage(data);
|
|
673
705
|
this.sendMessage(peer, id, node.encoded);
|
|
674
706
|
}
|
|
@@ -692,21 +724,20 @@ class Peernet {
|
|
|
692
724
|
const { id, proto } = message;
|
|
693
725
|
this.bw.down += proto.encoded.length;
|
|
694
726
|
switch (proto.name) {
|
|
695
|
-
case
|
|
727
|
+
case "peernet-dht": {
|
|
696
728
|
this.handleDHT(peer, id, proto);
|
|
697
729
|
break;
|
|
698
730
|
}
|
|
699
|
-
case
|
|
731
|
+
case "peernet-data": {
|
|
700
732
|
this.handleData(peer, id, proto);
|
|
701
733
|
break;
|
|
702
734
|
}
|
|
703
|
-
case
|
|
735
|
+
case "peernet-request": {
|
|
704
736
|
this.handleRequest(peer, id, proto);
|
|
705
737
|
break;
|
|
706
738
|
}
|
|
707
|
-
case
|
|
708
|
-
|
|
709
|
-
globalSub.publish(proto.decoded.topic, proto.decoded.data);
|
|
739
|
+
case "peernet-ps": {
|
|
740
|
+
globalSub.publish(new TextDecoder().decode(proto.decoded.topic), proto.decoded.data);
|
|
710
741
|
}
|
|
711
742
|
}
|
|
712
743
|
}
|
|
@@ -717,14 +748,14 @@ class Peernet {
|
|
|
717
748
|
*/
|
|
718
749
|
async walk(hash) {
|
|
719
750
|
if (!hash)
|
|
720
|
-
throw new Error(
|
|
721
|
-
const data = await new globalThis.peernet.protos[
|
|
751
|
+
throw new Error("hash expected, received undefined");
|
|
752
|
+
const data = await new globalThis.peernet.protos["peernet-dht"]({ hash });
|
|
722
753
|
const walk = async (peer, peerId) => {
|
|
723
754
|
const node = await this.prepareMessage(data);
|
|
724
755
|
let result = await peer.request(node.encoded);
|
|
725
756
|
result = new Uint8Array(Object.values(result));
|
|
726
757
|
const proto = await protoFor(result);
|
|
727
|
-
if (proto.name !==
|
|
758
|
+
if (proto.name !== "peernet-dht-response")
|
|
728
759
|
throw dhtError(proto.name);
|
|
729
760
|
const peerInfo = {
|
|
730
761
|
...peer.connectionStats,
|
|
@@ -750,7 +781,8 @@ class Peernet {
|
|
|
750
781
|
let providers = this.dht.providersFor(hash);
|
|
751
782
|
// walk the network to find a provider
|
|
752
783
|
let tries = 0;
|
|
753
|
-
while (!providers && tries < 3 ||
|
|
784
|
+
while ((!providers && tries < 3) ||
|
|
785
|
+
(Object.keys(providers).length === 0 && tries < 3)) {
|
|
754
786
|
tries += 1;
|
|
755
787
|
await this.walk(hash);
|
|
756
788
|
providers = this.dht.providersFor(hash);
|
|
@@ -764,7 +796,7 @@ class Peernet {
|
|
|
764
796
|
const data = await blockStore.has(hash);
|
|
765
797
|
if (data)
|
|
766
798
|
return blockStore.get(hash);
|
|
767
|
-
return this.requestData(hash,
|
|
799
|
+
return this.requestData(hash, "block");
|
|
768
800
|
},
|
|
769
801
|
put: async (hash, data) => {
|
|
770
802
|
if (await blockStore.has(hash))
|
|
@@ -780,7 +812,7 @@ class Peernet {
|
|
|
780
812
|
const data = await transactionStore.has(hash);
|
|
781
813
|
if (data)
|
|
782
814
|
return await transactionStore.get(hash);
|
|
783
|
-
return this.requestData(hash,
|
|
815
|
+
return this.requestData(hash, "transaction");
|
|
784
816
|
},
|
|
785
817
|
put: async (hash, data) => {
|
|
786
818
|
if (await transactionStore.has(hash))
|
|
@@ -792,7 +824,7 @@ class Peernet {
|
|
|
792
824
|
}
|
|
793
825
|
async requestData(hash, store) {
|
|
794
826
|
const providers = await this.providersFor(hash);
|
|
795
|
-
if (!providers || providers && Object.keys(providers).length === 0)
|
|
827
|
+
if (!providers || (providers && Object.keys(providers).length === 0))
|
|
796
828
|
throw nothingFoundError(hash);
|
|
797
829
|
debug(`found ${Object.keys(providers).length} provider(s) for ${hash}`);
|
|
798
830
|
// get closest peer on earth
|
|
@@ -803,7 +835,10 @@ class Peernet {
|
|
|
803
835
|
const id = closestPeer.id;
|
|
804
836
|
const peer = this.#connections[id];
|
|
805
837
|
if (peer?.connected) {
|
|
806
|
-
let data = await new globalThis.peernet.protos[
|
|
838
|
+
let data = await new globalThis.peernet.protos["peernet-data"]({
|
|
839
|
+
hash,
|
|
840
|
+
store: store?.name || store,
|
|
841
|
+
});
|
|
807
842
|
const node = await this.prepareMessage(data);
|
|
808
843
|
if (peer)
|
|
809
844
|
data = await peer.request(node.encoded);
|
|
@@ -842,7 +877,7 @@ class Peernet {
|
|
|
842
877
|
const message = await messageStore.has(hash);
|
|
843
878
|
if (message)
|
|
844
879
|
return await messageStore.get(hash);
|
|
845
|
-
return this.requestData(hash,
|
|
880
|
+
return this.requestData(hash, "message");
|
|
846
881
|
},
|
|
847
882
|
/**
|
|
848
883
|
* put message content
|
|
@@ -870,7 +905,7 @@ class Peernet {
|
|
|
870
905
|
const data = await dataStore.has(hash);
|
|
871
906
|
if (data)
|
|
872
907
|
return await dataStore.get(hash);
|
|
873
|
-
return this.requestData(hash,
|
|
908
|
+
return this.requestData(hash, "data");
|
|
874
909
|
},
|
|
875
910
|
/**
|
|
876
911
|
* put data content
|
|
@@ -898,7 +933,7 @@ class Peernet {
|
|
|
898
933
|
const data = await dataStore.has(hash);
|
|
899
934
|
if (data)
|
|
900
935
|
return await dataStore.get(hash);
|
|
901
|
-
return this.requestData(hash,
|
|
936
|
+
return this.requestData(hash, "data");
|
|
902
937
|
},
|
|
903
938
|
/**
|
|
904
939
|
* put data content
|
|
@@ -917,12 +952,15 @@ class Peernet {
|
|
|
917
952
|
async addFolder(files) {
|
|
918
953
|
const links = [];
|
|
919
954
|
for (const file of files) {
|
|
920
|
-
const fileNode = await new globalThis.peernet.protos[
|
|
955
|
+
const fileNode = await new globalThis.peernet.protos["peernet-file"](file);
|
|
921
956
|
const hash = await fileNode.hash;
|
|
922
957
|
await dataStore.put(hash, fileNode.encoded);
|
|
923
958
|
links.push({ hash, path: file.path });
|
|
924
959
|
}
|
|
925
|
-
const node = await new globalThis.peernet.protos[
|
|
960
|
+
const node = await new globalThis.peernet.protos["peernet-file"]({
|
|
961
|
+
path: "/",
|
|
962
|
+
links,
|
|
963
|
+
});
|
|
926
964
|
const hash = await node.hash;
|
|
927
965
|
await dataStore.put(hash, node.encoded);
|
|
928
966
|
return hash;
|
|
@@ -930,8 +968,10 @@ class Peernet {
|
|
|
930
968
|
async ls(hash, options) {
|
|
931
969
|
let data;
|
|
932
970
|
const has = await dataStore.has(hash);
|
|
933
|
-
data = has
|
|
934
|
-
|
|
971
|
+
data = has
|
|
972
|
+
? await dataStore.get(hash)
|
|
973
|
+
: await this.requestData(hash, "data");
|
|
974
|
+
const node = await new peernet.protos["peernet-file"](data);
|
|
935
975
|
await node.decode();
|
|
936
976
|
console.log(data);
|
|
937
977
|
const paths = [];
|
|
@@ -947,8 +987,10 @@ class Peernet {
|
|
|
947
987
|
async cat(hash, options) {
|
|
948
988
|
let data;
|
|
949
989
|
const has = await dataStore.has(hash);
|
|
950
|
-
data = has
|
|
951
|
-
|
|
990
|
+
data = has
|
|
991
|
+
? await dataStore.get(hash)
|
|
992
|
+
: await this.requestData(hash, "data");
|
|
993
|
+
const node = await new peernet.protos["peernet-file"](data);
|
|
952
994
|
if (node.decoded?.links.length > 0)
|
|
953
995
|
throw new Error(`${hash} is a directory`);
|
|
954
996
|
if (options?.pin)
|
|
@@ -986,7 +1028,7 @@ class Peernet {
|
|
|
986
1028
|
store = globalThis[`${store}Store`];
|
|
987
1029
|
if (!store)
|
|
988
1030
|
store = await this.whichStore([...this.stores], hash);
|
|
989
|
-
if (store && await store.has(hash))
|
|
1031
|
+
if (store && (await store.has(hash)))
|
|
990
1032
|
data = await store.get(hash);
|
|
991
1033
|
if (data)
|
|
992
1034
|
return data;
|
|
@@ -999,7 +1041,7 @@ class Peernet {
|
|
|
999
1041
|
* @param {Buffer} data
|
|
1000
1042
|
* @param {String} storeName - storeName to access
|
|
1001
1043
|
*/
|
|
1002
|
-
async put(hash, data, storeName =
|
|
1044
|
+
async put(hash, data, storeName = "data") {
|
|
1003
1045
|
const store = globalThis[`${storeName}Store`];
|
|
1004
1046
|
return store.put(hash, data);
|
|
1005
1047
|
}
|
|
@@ -1022,7 +1064,7 @@ class Peernet {
|
|
|
1022
1064
|
async publish(topic, data) {
|
|
1023
1065
|
// globalSub.publish(topic, data)
|
|
1024
1066
|
const id = Math.random().toString(36).slice(-12);
|
|
1025
|
-
data = await new globalThis.peernet.protos[
|
|
1067
|
+
data = await new globalThis.peernet.protos["peernet-ps"]({ data, topic });
|
|
1026
1068
|
for (const [peerId, peer] of Object.entries(this.#connections)) {
|
|
1027
1069
|
if (peerId !== this.id) {
|
|
1028
1070
|
const node = await this.prepareMessage(data);
|
|
@@ -1044,7 +1086,7 @@ class Peernet {
|
|
|
1044
1086
|
globalSub.subscribe(topic, callback);
|
|
1045
1087
|
}
|
|
1046
1088
|
async removePeer(peer) {
|
|
1047
|
-
console.log(
|
|
1089
|
+
console.log("removepeer", peer.id);
|
|
1048
1090
|
const id = peer.id;
|
|
1049
1091
|
await this.client._removePeer(peer);
|
|
1050
1092
|
if (this.client.peers[id]) {
|
|
@@ -1052,7 +1094,7 @@ class Peernet {
|
|
|
1052
1094
|
// if (this.client.peers[id][connection].connected === false) delete this.client.peers[id][connection]
|
|
1053
1095
|
// @ts-ignore
|
|
1054
1096
|
if (this.client.peers[id][connection].connected)
|
|
1055
|
-
return this.client.emit(
|
|
1097
|
+
return this.client.emit("peerconnect", connection);
|
|
1056
1098
|
}
|
|
1057
1099
|
}
|
|
1058
1100
|
}
|