@leofcoin/peernet 1.0.2 → 1.0.5
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/.travis.yml +27 -25
- package/LICENSE +21 -21
- package/README.md +64 -64
- package/deploy.js +8 -8
- package/exports/browser/browser-10ffabe1.js +56 -0
- package/exports/browser/{browser-2f0b2829.js → browser-e1cd4e67.js} +46 -38
- package/exports/browser/{client-95423644.js → client-d63a0806.js} +4 -3
- package/exports/browser/dht/dht.d.ts +30 -30
- package/exports/browser/discovery/peer-discovery.d.ts +7 -7
- package/exports/browser/errors/errors.d.ts +3 -3
- package/exports/browser/handlers/data.d.ts +2 -2
- package/exports/browser/handlers/message.d.ts +30 -30
- package/exports/browser/{index-3699fac4.js → index-ae8a0f11.js} +33 -29
- package/exports/browser/messages/chat.d.ts +6 -6
- package/exports/browser/messages/data-response.d.ts +6 -6
- package/exports/browser/messages/data.d.ts +10 -10
- package/exports/browser/messages/dht-response.d.ts +6 -6
- package/exports/browser/messages/dht.d.ts +14 -14
- package/exports/browser/messages/file-link.d.ts +10 -10
- package/exports/browser/messages/file.d.ts +10 -10
- package/exports/browser/messages/peer-response.d.ts +6 -6
- package/exports/browser/messages/peer.d.ts +6 -6
- package/exports/browser/messages/peernet.d.ts +6 -6
- package/exports/browser/messages/ps.d.ts +6 -6
- package/exports/browser/messages/request.d.ts +6 -6
- package/exports/browser/messages/response.d.ts +6 -6
- package/exports/browser/{messages-2214fcbb.js → messages-b724fbb6.js} +155 -154
- package/exports/browser/messages.d.ts +12 -12
- package/exports/browser/peer-info.d.ts +4 -4
- package/exports/browser/{peernet-e74b2091.js → peernet-76472a7f.js} +13594 -10531
- package/exports/browser/peernet.js +2 -1
- package/exports/browser/prompts/password/browser.d.ts +2 -2
- package/exports/browser/prompts/password/node.d.ts +2 -2
- package/exports/browser/proto/chat-message.proto.d.ts +7 -7
- package/exports/browser/proto/data-response.proto.d.ts +5 -5
- package/exports/browser/proto/data.proto.d.ts +5 -5
- package/exports/browser/proto/dht-response.proto.d.ts +5 -5
- package/exports/browser/proto/dht.proto.d.ts +5 -5
- package/exports/browser/proto/file-link.proto.d.ts +6 -6
- package/exports/browser/proto/file.proto.d.ts +6 -6
- package/exports/browser/proto/peer-response.proto.d.ts +4 -4
- package/exports/browser/proto/peer.proto.d.ts +4 -4
- package/exports/browser/proto/peernet.proto.d.ts +8 -8
- package/exports/browser/proto/ps.proto.d.ts +5 -5
- package/exports/browser/proto/request.proto.d.ts +4 -4
- package/exports/browser/proto/response.proto.d.ts +4 -4
- package/exports/browser/qr-scanner-worker.min-c002e984.js +100 -0
- package/exports/browser/utils/utils.d.ts +7 -7
- package/exports/dht/dht.d.ts +30 -30
- package/exports/discovery/peer-discovery.d.ts +7 -7
- package/exports/errors/errors.d.ts +3 -3
- package/exports/handlers/data.d.ts +2 -2
- package/exports/handlers/message.d.ts +30 -30
- package/exports/messages/chat.d.ts +6 -6
- package/exports/messages/data-response.d.ts +6 -6
- package/exports/messages/data.d.ts +10 -10
- package/exports/messages/dht-response.d.ts +6 -6
- package/exports/messages/dht.d.ts +14 -14
- package/exports/messages/file-link.d.ts +10 -10
- package/exports/messages/file.d.ts +10 -10
- package/exports/messages/peer-response.d.ts +6 -6
- package/exports/messages/peer.d.ts +6 -6
- package/exports/messages/peernet.d.ts +6 -6
- package/exports/messages/ps.d.ts +6 -6
- package/exports/messages/request.d.ts +6 -6
- package/exports/messages/response.d.ts +6 -6
- package/exports/{messages-75fe56a4.js → messages-65501ef9.js} +152 -152
- package/exports/messages.d.ts +12 -12
- package/exports/peer-info.d.ts +4 -4
- package/exports/peernet.js +972 -968
- package/exports/prompts/password/browser.d.ts +2 -2
- package/exports/prompts/password/node.d.ts +2 -2
- package/exports/proto/chat-message.proto.d.ts +7 -7
- package/exports/proto/data-response.proto.d.ts +5 -5
- package/exports/proto/data.proto.d.ts +5 -5
- package/exports/proto/dht-response.proto.d.ts +5 -5
- package/exports/proto/dht.proto.d.ts +5 -5
- package/exports/proto/file-link.proto.d.ts +6 -6
- package/exports/proto/file.proto.d.ts +6 -6
- package/exports/proto/peer-response.proto.d.ts +4 -4
- package/exports/proto/peer.proto.d.ts +4 -4
- package/exports/proto/peernet.proto.d.ts +8 -8
- package/exports/proto/ps.proto.d.ts +5 -5
- package/exports/proto/request.proto.d.ts +4 -4
- package/exports/proto/response.proto.d.ts +4 -4
- package/exports/src/prompts/password.js +3 -3
- package/exports/utils/utils.d.ts +7 -7
- package/index.html +19 -19
- package/package.json +59 -55
- package/rollup.config.js +53 -53
- package/src/dht/dht.js +119 -119
- package/src/discovery/peer-discovery.js +75 -75
- package/src/handlers/data.js +12 -12
- package/src/handlers/message.js +34 -34
- package/src/identity.ts +83 -80
- 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 +699 -699
- package/src/prompts/password/node.js +5 -5
- package/src/proto/chat-message.proto.js +6 -6
- package/src/utils/utils.js +78 -78
- package/test/client.js +6 -6
- 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 +47 -47
- package/test2.js +9 -9
- package/test3.js +15 -15
- package/test4.js +7 -7
- package/tsconfig.json +12 -12
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/codec-format-interface.js.html +0 -637
- package/coverage/lcov-report/dht-response.js.html +0 -193
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -131
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -196
- package/coverage/lcov.info +0 -199
- package/exports/browser/browser-3c1d0477.js +0 -73
package/src/dht/dht.js
CHANGED
|
@@ -1,119 +1,119 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Keep history of fetched address and ptr
|
|
3
|
-
* @property {Object} address
|
|
4
|
-
* @property {Object} ptr
|
|
5
|
-
*/
|
|
6
|
-
const lastFetched = {
|
|
7
|
-
address: {
|
|
8
|
-
value: undefined,
|
|
9
|
-
timestamp: 0,
|
|
10
|
-
},
|
|
11
|
-
ptr: {
|
|
12
|
-
value: undefined,
|
|
13
|
-
timestamp: 0,
|
|
14
|
-
},
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const getAddress = async () => {
|
|
18
|
-
const {address} = lastFetched
|
|
19
|
-
const now = Math.round(new Date().getTime() / 1000);
|
|
20
|
-
if (now - address.timestamp > 1200000) {
|
|
21
|
-
address.value = await fetch('https://icanhazip.com/')
|
|
22
|
-
address.value = await address.value.text()
|
|
23
|
-
address.timestamp = Math.round(new Date().getTime() / 1000);
|
|
24
|
-
lastFetched.address = address;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return address.value
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const degreesToRadians = (degrees) => {
|
|
31
|
-
return degrees * Math.PI / 180;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const distanceInKmBetweenEarthCoordinates = (lat1, lon1, lat2, lon2) => {
|
|
35
|
-
const earthRadiusKm = 6371;
|
|
36
|
-
|
|
37
|
-
const dLat = degreesToRadians(lat2-lat1);
|
|
38
|
-
const dLon = degreesToRadians(lon2-lon1);
|
|
39
|
-
|
|
40
|
-
lat1 = degreesToRadians(lat1);
|
|
41
|
-
lat2 = degreesToRadians(lat2);
|
|
42
|
-
const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
|
|
43
|
-
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
|
|
44
|
-
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
|
|
45
|
-
return earthRadiusKm * c;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export default class DhtEarth {
|
|
49
|
-
/**
|
|
50
|
-
*
|
|
51
|
-
*/
|
|
52
|
-
constructor() {
|
|
53
|
-
this.providerMap = new Map();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* @param {Object} address
|
|
58
|
-
* @return {Object} {latitude: lat, longitude: lon}
|
|
59
|
-
*/
|
|
60
|
-
async getCoordinates(address) {
|
|
61
|
-
// const {address} = parseAddress(provider)
|
|
62
|
-
const request = `https://whereis.leofcoin.org/?ip=${address}`
|
|
63
|
-
let response = await fetch(request)
|
|
64
|
-
response = await response.json()
|
|
65
|
-
const {lat, lon} = response;
|
|
66
|
-
return {latitude: lat, longitude: lon}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* @param {Object} peer
|
|
71
|
-
* @param {Object} provider
|
|
72
|
-
* @return {Object} {provider, distance}
|
|
73
|
-
*/
|
|
74
|
-
async getDistance(peer, provider) {
|
|
75
|
-
const {latitude, longitude} = await this.getCoordinates(provider.address)
|
|
76
|
-
return {provider, distance: distanceInKmBetweenEarthCoordinates(peer.latitude, peer.longitude, latitude, longitude)}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* @param {Array} providers
|
|
81
|
-
* @return {Object} closestPeer
|
|
82
|
-
*/
|
|
83
|
-
async closestPeer(providers) {
|
|
84
|
-
let all = []
|
|
85
|
-
const address = await getAddress();
|
|
86
|
-
const peerLoc = await this.getCoordinates(address)
|
|
87
|
-
|
|
88
|
-
for (const provider of providers) {
|
|
89
|
-
if (provider.address === '127.0.0.1') all.push({provider, distance: 0})
|
|
90
|
-
else all.push(this.getDistance(peerLoc, provider))
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
all = await Promise.all(all);
|
|
94
|
-
all = all.sort((previous, current) => previous.distance - current.distance)
|
|
95
|
-
return all[0].provider;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* @param {String} hash
|
|
100
|
-
* @return {Array} providers
|
|
101
|
-
*/
|
|
102
|
-
providersFor(hash) {
|
|
103
|
-
return this.providerMap.get(hash);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* @param {String} address
|
|
108
|
-
* @param {String} hash
|
|
109
|
-
* @return {Array} providers
|
|
110
|
-
*/
|
|
111
|
-
async addProvider(address, hash) {
|
|
112
|
-
let providers = [];
|
|
113
|
-
if (this.providerMap.has(hash)) providers = this.providerMap.get(hash)
|
|
114
|
-
|
|
115
|
-
providers = new Set([...providers, address])
|
|
116
|
-
this.providerMap.set(hash, providers)
|
|
117
|
-
return providers;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Keep history of fetched address and ptr
|
|
3
|
+
* @property {Object} address
|
|
4
|
+
* @property {Object} ptr
|
|
5
|
+
*/
|
|
6
|
+
const lastFetched = {
|
|
7
|
+
address: {
|
|
8
|
+
value: undefined,
|
|
9
|
+
timestamp: 0,
|
|
10
|
+
},
|
|
11
|
+
ptr: {
|
|
12
|
+
value: undefined,
|
|
13
|
+
timestamp: 0,
|
|
14
|
+
},
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const getAddress = async () => {
|
|
18
|
+
const {address} = lastFetched
|
|
19
|
+
const now = Math.round(new Date().getTime() / 1000);
|
|
20
|
+
if (now - address.timestamp > 1200000) {
|
|
21
|
+
address.value = await fetch('https://icanhazip.com/')
|
|
22
|
+
address.value = await address.value.text()
|
|
23
|
+
address.timestamp = Math.round(new Date().getTime() / 1000);
|
|
24
|
+
lastFetched.address = address;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return address.value
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const degreesToRadians = (degrees) => {
|
|
31
|
+
return degrees * Math.PI / 180;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const distanceInKmBetweenEarthCoordinates = (lat1, lon1, lat2, lon2) => {
|
|
35
|
+
const earthRadiusKm = 6371;
|
|
36
|
+
|
|
37
|
+
const dLat = degreesToRadians(lat2-lat1);
|
|
38
|
+
const dLon = degreesToRadians(lon2-lon1);
|
|
39
|
+
|
|
40
|
+
lat1 = degreesToRadians(lat1);
|
|
41
|
+
lat2 = degreesToRadians(lat2);
|
|
42
|
+
const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
|
|
43
|
+
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
|
|
44
|
+
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
|
|
45
|
+
return earthRadiusKm * c;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export default class DhtEarth {
|
|
49
|
+
/**
|
|
50
|
+
*
|
|
51
|
+
*/
|
|
52
|
+
constructor() {
|
|
53
|
+
this.providerMap = new Map();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {Object} address
|
|
58
|
+
* @return {Object} {latitude: lat, longitude: lon}
|
|
59
|
+
*/
|
|
60
|
+
async getCoordinates(address) {
|
|
61
|
+
// const {address} = parseAddress(provider)
|
|
62
|
+
const request = `https://whereis.leofcoin.org/?ip=${address}`
|
|
63
|
+
let response = await fetch(request)
|
|
64
|
+
response = await response.json()
|
|
65
|
+
const {lat, lon} = response;
|
|
66
|
+
return {latitude: lat, longitude: lon}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @param {Object} peer
|
|
71
|
+
* @param {Object} provider
|
|
72
|
+
* @return {Object} {provider, distance}
|
|
73
|
+
*/
|
|
74
|
+
async getDistance(peer, provider) {
|
|
75
|
+
const {latitude, longitude} = await this.getCoordinates(provider.address)
|
|
76
|
+
return {provider, distance: distanceInKmBetweenEarthCoordinates(peer.latitude, peer.longitude, latitude, longitude)}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @param {Array} providers
|
|
81
|
+
* @return {Object} closestPeer
|
|
82
|
+
*/
|
|
83
|
+
async closestPeer(providers) {
|
|
84
|
+
let all = []
|
|
85
|
+
const address = await getAddress();
|
|
86
|
+
const peerLoc = await this.getCoordinates(address)
|
|
87
|
+
|
|
88
|
+
for (const provider of providers) {
|
|
89
|
+
if (provider.address === '127.0.0.1') all.push({provider, distance: 0})
|
|
90
|
+
else all.push(this.getDistance(peerLoc, provider))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
all = await Promise.all(all);
|
|
94
|
+
all = all.sort((previous, current) => previous.distance - current.distance)
|
|
95
|
+
return all[0].provider;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @param {String} hash
|
|
100
|
+
* @return {Array} providers
|
|
101
|
+
*/
|
|
102
|
+
providersFor(hash) {
|
|
103
|
+
return this.providerMap.get(hash);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* @param {String} address
|
|
108
|
+
* @param {String} hash
|
|
109
|
+
* @return {Array} providers
|
|
110
|
+
*/
|
|
111
|
+
async addProvider(address, hash) {
|
|
112
|
+
let providers = [];
|
|
113
|
+
if (this.providerMap.has(hash)) providers = this.providerMap.get(hash)
|
|
114
|
+
|
|
115
|
+
providers = new Set([...providers, address])
|
|
116
|
+
this.providerMap.set(hash, providers)
|
|
117
|
+
return providers;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
import { protoFor } from './../utils/utils.js'
|
|
2
|
-
|
|
3
|
-
export default class PeerDiscovery {
|
|
4
|
-
constructor(id) {
|
|
5
|
-
this.id = id
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
_getPeerId(id) {
|
|
9
|
-
if (!peernet.peerMap || peernet.peerMap && peernet.peerMap.size === 0) return false
|
|
10
|
-
|
|
11
|
-
for (const entry of [...peernet.peerMap.entries()]) {
|
|
12
|
-
for (const _id of entry[1]) {
|
|
13
|
-
if (_id === id) return entry[0]
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async discover(peer) {
|
|
19
|
-
let id = this._getPeerId(peer.id)
|
|
20
|
-
if (id) return id
|
|
21
|
-
const data = await new peernet.protos['peernet-peer']({id: this.id})
|
|
22
|
-
const node = await peernet.prepareMessage(peer.id, data.encoded)
|
|
23
|
-
|
|
24
|
-
let response = await peer.request(node.encoded)
|
|
25
|
-
response = await protoFor(response)
|
|
26
|
-
response = await new peernet.protos['peernet-peer-response'](response.decoded.data)
|
|
27
|
-
|
|
28
|
-
id = response.decoded.id
|
|
29
|
-
if (id === this.id) return;
|
|
30
|
-
|
|
31
|
-
if (!peernet.peerMap.has(id)) peernet.peerMap.set(id, [peer.id])
|
|
32
|
-
else {
|
|
33
|
-
const connections = peernet.peerMap.get(id)
|
|
34
|
-
if (connections.indexOf(peer.id) === -1) {
|
|
35
|
-
connections.push(peer.id)
|
|
36
|
-
peernet.peerMap.set(peer.id, connections)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return id
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async discoverHandler(message, peer) {
|
|
43
|
-
const {id, proto} = message
|
|
44
|
-
// if (typeof message.data === 'string') message.data = Buffer.from(message.data)
|
|
45
|
-
if (proto.name === 'peernet-peer') {
|
|
46
|
-
const from = proto.decoded.id
|
|
47
|
-
if (from === this.id) return;
|
|
48
|
-
|
|
49
|
-
if (!peernet.peerMap.has(from)) peernet.peerMap.set(from, [peer.id])
|
|
50
|
-
else {
|
|
51
|
-
const connections = peernet.peerMap.get(from)
|
|
52
|
-
if (connections.indexOf(peer.id) === -1) {
|
|
53
|
-
connections.push(peer.id)
|
|
54
|
-
peernet.peerMap.set(from, connections)
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
const data = await new peernet.protos['peernet-peer-response']({id: this.id})
|
|
58
|
-
const node = await peernet.prepareMessage(from, data.encoded)
|
|
59
|
-
|
|
60
|
-
peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})))
|
|
61
|
-
} else if (proto.name === 'peernet-peer-response') {
|
|
62
|
-
const from = proto.decoded.id
|
|
63
|
-
if (from === this.id) return;
|
|
64
|
-
|
|
65
|
-
if (!peernet.peerMap.has(from)) peernet.peerMap.set(from, [peer.id])
|
|
66
|
-
else {
|
|
67
|
-
const connections = peernet.peerMap.get(from)
|
|
68
|
-
if (connections.indexOf(peer.id) === -1) {
|
|
69
|
-
connections.push(peer.id)
|
|
70
|
-
peernet.peerMap.set(from, connections)
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
1
|
+
import { protoFor } from './../utils/utils.js'
|
|
2
|
+
|
|
3
|
+
export default class PeerDiscovery {
|
|
4
|
+
constructor(id) {
|
|
5
|
+
this.id = id
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
_getPeerId(id) {
|
|
9
|
+
if (!peernet.peerMap || peernet.peerMap && peernet.peerMap.size === 0) return false
|
|
10
|
+
|
|
11
|
+
for (const entry of [...peernet.peerMap.entries()]) {
|
|
12
|
+
for (const _id of entry[1]) {
|
|
13
|
+
if (_id === id) return entry[0]
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async discover(peer) {
|
|
19
|
+
let id = this._getPeerId(peer.id)
|
|
20
|
+
if (id) return id
|
|
21
|
+
const data = await new peernet.protos['peernet-peer']({id: this.id})
|
|
22
|
+
const node = await peernet.prepareMessage(peer.id, data.encoded)
|
|
23
|
+
|
|
24
|
+
let response = await peer.request(node.encoded)
|
|
25
|
+
response = await protoFor(response)
|
|
26
|
+
response = await new peernet.protos['peernet-peer-response'](response.decoded.data)
|
|
27
|
+
|
|
28
|
+
id = response.decoded.id
|
|
29
|
+
if (id === this.id) return;
|
|
30
|
+
|
|
31
|
+
if (!peernet.peerMap.has(id)) peernet.peerMap.set(id, [peer.id])
|
|
32
|
+
else {
|
|
33
|
+
const connections = peernet.peerMap.get(id)
|
|
34
|
+
if (connections.indexOf(peer.id) === -1) {
|
|
35
|
+
connections.push(peer.id)
|
|
36
|
+
peernet.peerMap.set(peer.id, connections)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return id
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async discoverHandler(message, peer) {
|
|
43
|
+
const {id, proto} = message
|
|
44
|
+
// if (typeof message.data === 'string') message.data = Buffer.from(message.data)
|
|
45
|
+
if (proto.name === 'peernet-peer') {
|
|
46
|
+
const from = proto.decoded.id
|
|
47
|
+
if (from === this.id) return;
|
|
48
|
+
|
|
49
|
+
if (!peernet.peerMap.has(from)) peernet.peerMap.set(from, [peer.id])
|
|
50
|
+
else {
|
|
51
|
+
const connections = peernet.peerMap.get(from)
|
|
52
|
+
if (connections.indexOf(peer.id) === -1) {
|
|
53
|
+
connections.push(peer.id)
|
|
54
|
+
peernet.peerMap.set(from, connections)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const data = await new peernet.protos['peernet-peer-response']({id: this.id})
|
|
58
|
+
const node = await peernet.prepareMessage(from, data.encoded)
|
|
59
|
+
|
|
60
|
+
peer.write(Buffer.from(JSON.stringify({id, data: node.encoded})))
|
|
61
|
+
} else if (proto.name === 'peernet-peer-response') {
|
|
62
|
+
const from = proto.decoded.id
|
|
63
|
+
if (from === this.id) return;
|
|
64
|
+
|
|
65
|
+
if (!peernet.peerMap.has(from)) peernet.peerMap.set(from, [peer.id])
|
|
66
|
+
else {
|
|
67
|
+
const connections = peernet.peerMap.get(from)
|
|
68
|
+
if (connections.indexOf(peer.id) === -1) {
|
|
69
|
+
connections.push(peer.id)
|
|
70
|
+
peernet.peerMap.set(from, connections)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
package/src/handlers/data.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { protoFor } from './../utils/utils.js'
|
|
2
|
-
|
|
3
|
-
const dataHandler = async message => {
|
|
4
|
-
if (!message) return
|
|
5
|
-
|
|
6
|
-
const {data, id, from} = message
|
|
7
|
-
const proto = await protoFor(data)
|
|
8
|
-
|
|
9
|
-
peernet._protoHandler({id, proto}, peernet.client.connections[from], from)
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export default dataHandler
|
|
1
|
+
import { protoFor } from './../utils/utils.js'
|
|
2
|
+
|
|
3
|
+
const dataHandler = async message => {
|
|
4
|
+
if (!message) return
|
|
5
|
+
|
|
6
|
+
const {data, id, from} = message
|
|
7
|
+
const proto = await protoFor(data)
|
|
8
|
+
|
|
9
|
+
peernet._protoHandler({id, proto}, peernet.client.connections[from], from)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default dataHandler
|
package/src/handlers/message.js
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
export default class MessageHandler {
|
|
2
|
-
constructor(network) {
|
|
3
|
-
this.network = network
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* hash and sign message
|
|
7
|
-
*
|
|
8
|
-
* @param {object} message
|
|
9
|
-
* @param {Buffer} message.from peer id
|
|
10
|
-
* @param {Buffer} message.to peer id
|
|
11
|
-
* @param {string} message.data Peernet message
|
|
12
|
-
* (PeernetMessage excluded) encoded as a string
|
|
13
|
-
* @return message
|
|
14
|
-
*/
|
|
15
|
-
async hashAndSignMessage(message) {
|
|
16
|
-
const hash = await message.peernetHash
|
|
17
|
-
message.decoded.signature = globalThis.identity.sign(hash.buffer)
|
|
18
|
-
return message
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @param {String} from - peer id
|
|
23
|
-
* @param {String} to - peer id
|
|
24
|
-
* @param {String|PeernetMessage} data - data encoded message string
|
|
25
|
-
* or the messageNode itself
|
|
26
|
-
*/
|
|
27
|
-
async prepareMessage(message) {
|
|
28
|
-
if (message.keys.includes('signature')) {
|
|
29
|
-
message = await this.hashAndSignMessage(message)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return message
|
|
33
|
-
}
|
|
34
|
-
}
|
|
1
|
+
export default class MessageHandler {
|
|
2
|
+
constructor(network) {
|
|
3
|
+
this.network = network
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* hash and sign message
|
|
7
|
+
*
|
|
8
|
+
* @param {object} message
|
|
9
|
+
* @param {Buffer} message.from peer id
|
|
10
|
+
* @param {Buffer} message.to peer id
|
|
11
|
+
* @param {string} message.data Peernet message
|
|
12
|
+
* (PeernetMessage excluded) encoded as a string
|
|
13
|
+
* @return message
|
|
14
|
+
*/
|
|
15
|
+
async hashAndSignMessage(message) {
|
|
16
|
+
const hash = await message.peernetHash
|
|
17
|
+
message.decoded.signature = globalThis.identity.sign(hash.buffer)
|
|
18
|
+
return message
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @param {String} from - peer id
|
|
23
|
+
* @param {String} to - peer id
|
|
24
|
+
* @param {String|PeernetMessage} data - data encoded message string
|
|
25
|
+
* or the messageNode itself
|
|
26
|
+
*/
|
|
27
|
+
async prepareMessage(message) {
|
|
28
|
+
if (message.keys.includes('signature')) {
|
|
29
|
+
message = await this.hashAndSignMessage(message)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return message
|
|
33
|
+
}
|
|
34
|
+
}
|
package/src/identity.ts
CHANGED
|
@@ -1,81 +1,84 @@
|
|
|
1
|
-
import MultiWallet from '@leofcoin/multi-wallet'
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
await
|
|
42
|
-
await
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
1
|
+
import MultiWallet from '@leofcoin/multi-wallet'
|
|
2
|
+
import base58 from '@vandeurenglenn/base58'
|
|
3
|
+
import {encrypt, decrypt} from '@leofcoin/identity-utils'
|
|
4
|
+
import QrScanner from 'qr-scanner'
|
|
5
|
+
import qrcode from 'qrcode'
|
|
6
|
+
import { readFile } from 'fs/promises'
|
|
7
|
+
|
|
8
|
+
export default class Identity {
|
|
9
|
+
#wallet: MultiWallet
|
|
10
|
+
network: MultiWallet.network
|
|
11
|
+
id: string
|
|
12
|
+
|
|
13
|
+
constructor(network: string) {
|
|
14
|
+
this.network = network
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
get accounts(): Promise<[[name: string, externalAddress: string, internalAddress: string]]> {
|
|
18
|
+
return this.getAccounts()
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async getAccounts(): Promise<[[name: string, externalAddress: string, internalAddress: string]]> {
|
|
22
|
+
let accounts = await globalThis.walletStore.get('accounts')
|
|
23
|
+
accounts = new TextDecoder().decode(accounts)
|
|
24
|
+
return JSON.parse(accounts)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async load(password?: string): Promise<void> {
|
|
28
|
+
if (password && password.includes('.txt')) password = (await readFile(password)).toString()
|
|
29
|
+
if (!password) {
|
|
30
|
+
const importee: { default: () => Promise<string> } = await import('./prompts/password.js')
|
|
31
|
+
password = await importee.default()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const accountExists = await globalThis.accountStore.has('public')
|
|
35
|
+
if (accountExists) {
|
|
36
|
+
const pub = await globalThis.accountStore.get('public')
|
|
37
|
+
this.id = JSON.parse(new TextDecoder().decode(pub)).walletId;
|
|
38
|
+
const selected = await globalThis.walletStore.get('selected-account')
|
|
39
|
+
globalThis.peernet.selectedAccount = new TextDecoder().decode(selected)
|
|
40
|
+
} else {
|
|
41
|
+
const importee = await import(/* webpackChunkName: "generate-account" */ '@leofcoin/generate-account')
|
|
42
|
+
const {identity, accounts} = await importee.default(password, this.network)
|
|
43
|
+
await globalThis.accountStore.put('public', JSON.stringify({walletId: identity.walletId}));
|
|
44
|
+
|
|
45
|
+
await globalThis.walletStore.put('version', String(1))
|
|
46
|
+
await globalThis.walletStore.put('accounts', JSON.stringify(accounts))
|
|
47
|
+
await globalThis.walletStore.put('selected-account', accounts[0][1])
|
|
48
|
+
await globalThis.walletStore.put('identity', JSON.stringify(identity))
|
|
49
|
+
|
|
50
|
+
globalThis.peernet.selectedAccount = accounts[0][1]
|
|
51
|
+
this.id = identity.walletId
|
|
52
|
+
}
|
|
53
|
+
const identity = JSON.parse(new TextDecoder().decode(await globalThis.walletStore.get('identity')))
|
|
54
|
+
this.#wallet = new MultiWallet(this.network)
|
|
55
|
+
const multiWIF = await decrypt(password, base58.decode(identity.multiWIF))
|
|
56
|
+
await this.#wallet.fromMultiWif(multiWIF)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
sign(hash: Uint8Array) {
|
|
60
|
+
return this.#wallet.sign(hash.subarray(0, 32))
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async export(password: string) {
|
|
64
|
+
const multiWIF = this.#wallet.toMultiWif()
|
|
65
|
+
const encypted = await encrypt(password, multiWIF)
|
|
66
|
+
return base58.encode(encypted)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async import(password, encrypted: base58String) {
|
|
70
|
+
this.#wallet = new MultiWallet(this.network)
|
|
71
|
+
const decrypted = await decrypt(password, base58.decode(encrypted))
|
|
72
|
+
await this.#wallet.fromMultiWif(decrypted)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async exportQR(password: string) {
|
|
76
|
+
const exported = await this.export(password)
|
|
77
|
+
return globalThis.navigator ? await qrcode.toDataURL(exported) : await qrcode.toString(exported, {type: 'terminal'})
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async importQR(image: File | Blob , password: string) {
|
|
81
|
+
const multiWIF = QrScanner.scanImage(image)
|
|
82
|
+
return this.import(password, multiWIF)
|
|
83
|
+
}
|
|
81
84
|
}
|