@leofcoin/peernet 0.10.8 → 0.11.2

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.
Files changed (78) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +49 -49
  3. package/coverage/lcov-report/block-navigation.js +8 -0
  4. package/coverage/lcov-report/codec-format-interface.js.html +224 -120
  5. package/coverage/lcov-report/dht-response.js.html +44 -39
  6. package/coverage/lcov-report/index.html +39 -64
  7. package/coverage/lcov-report/sorter.js +26 -0
  8. package/coverage/lcov.info +164 -424
  9. package/dist/browser/326.peernet.js +29 -0
  10. package/dist/browser/peernet.js +84258 -95769
  11. package/dist/commonjs/client-1a1f75e6.js +324 -0
  12. package/dist/commonjs/{codec-6367213c.js → codec-8c8c652f.js} +198 -188
  13. package/dist/commonjs/codec-format-interface.js +169 -152
  14. package/dist/commonjs/codec.js +4 -4
  15. package/dist/commonjs/dht-response.js +13 -13
  16. package/dist/commonjs/dht.js +24 -24
  17. package/dist/commonjs/hash.js +151 -141
  18. package/dist/commonjs/{http-a94c5a81.js → http-4bc6caeb.js} +19 -15
  19. package/dist/commonjs/peernet-message.js +15 -15
  20. package/dist/commonjs/peernet.js +1901 -1794
  21. package/dist/commonjs/request.js +13 -13
  22. package/dist/commonjs/response.js +13 -13
  23. package/dist/module/peernet.js +2462 -2348
  24. package/index.html +5 -7
  25. package/package.json +22 -14
  26. package/rollup.config.js +33 -5
  27. package/rollup0.config.js +7 -0
  28. package/src/client.js +75 -75
  29. package/src/codec/codec-format-interface.js +172 -155
  30. package/src/codec/codec.js +124 -114
  31. package/src/codec/codecs.js +79 -79
  32. package/src/dht/dht.js +121 -121
  33. package/src/discovery/peer-discovery.js +75 -75
  34. package/src/handlers/message.js +50 -52
  35. package/src/hash/hash.js +155 -145
  36. package/src/http/client/http-client.js +44 -44
  37. package/src/messages/chat-message.js +14 -14
  38. package/src/messages/data-response.js +14 -14
  39. package/src/messages/data.js +18 -18
  40. package/src/messages/dht-response.js +14 -15
  41. package/src/messages/dht.js +25 -25
  42. package/src/messages/peer-response.js +14 -14
  43. package/src/messages/peer.js +14 -14
  44. package/src/messages/peernet-message.js +14 -14
  45. package/src/messages/ps.js +14 -14
  46. package/src/messages/request.js +14 -14
  47. package/src/messages/response.js +14 -14
  48. package/src/peer.js +67 -67
  49. package/src/peernet.js +614 -697
  50. package/src/proto/chat-message.proto.js +7 -7
  51. package/src/proto/peernet.proto.js +2 -2
  52. package/src/utils/utils.js +78 -78
  53. package/test/codec.js +3 -2
  54. package/test/messages.js +7 -4
  55. package/test.js +11 -4
  56. package/webpack.config.js +41 -0
  57. package/coverage/lcov-report/codec.js.html +0 -677
  58. package/coverage/lcov-report/hash.js.html +0 -551
  59. package/debug.log +0 -3
  60. package/dist/browser/peernet.js.tmp-browserify-14074318104595318069 +0 -0
  61. package/dist/browser/peernet.js.tmp-browserify-45407634493269122267 +0 -0
  62. package/dist/browser/peernet.js.tmp-browserify-53722389064799025427 +0 -0
  63. package/dist/browser/peernet.js.tmp-browserify-96323030449218949300 +0 -0
  64. package/dist/codec/codec-format-interface.js +0 -433
  65. package/dist/codec/codec.js +0 -199
  66. package/dist/commonjs/codec-73adfc0f.js +0 -205
  67. package/dist/commonjs/http-2c603501.js +0 -324
  68. package/dist/commonjs/http-42a6e555.js +0 -324
  69. package/dist/commonjs/http-43f4fafe.js +0 -324
  70. package/dist/commonjs/peernet-message-b6925673.js +0 -32
  71. package/dist/hash/hash.js +0 -340
  72. package/dist/messages/dht-response.js +0 -454
  73. package/dist/messages/dht.js +0 -453
  74. package/dist/messages/peernet.js +0 -456
  75. package/dist/module/http-273664bd.js +0 -317
  76. package/dist/module/http-8fe3c0d7.js +0 -317
  77. package/dist/module/http-c780c991.js +0 -317
  78. package/dist/module/http-f13e0d77.js +0 -317
@@ -1,114 +1,124 @@
1
- import varint from 'varint';
2
- import bs32 from 'bs32';
3
- import bs58 from 'bs58';
4
- import isHex from 'is-hex';
5
- import codecs from './codecs'
6
-
7
- export default class PeernetCodec {
8
- get codecs() {
9
- return {...globalThis.peernet.codecs, ...codecs}
10
- }
11
- constructor(buffer) {
12
- if (buffer) {
13
- if (Buffer.isBuffer(buffer)) {
14
- const codec = varint.decode(buffer);
15
- const name = this.getCodecName(codec)
16
-
17
- if (name) {
18
- this.name = name
19
- this.encoded = buffer
20
- this.decode(buffer)
21
- } else {
22
- this.encode(buffer)
23
- }
24
- }
25
- if (typeof buffer === 'string') {
26
- if (this.codecs[buffer]) this.fromName(buffer)
27
- else if (isHex(buffer)) this.fromHex(buffer)
28
- else if (bs32.test(buffer)) this.fromBs32(buffer)
29
- else this.fromBs58(buffer)
30
- }
31
- if (!isNaN(buffer)) if (this.codecs[this.getCodecName(buffer)]) this.fromCodec(buffer)
32
- }
33
- }
34
-
35
- fromEncoded(encoded) {
36
- const codec = varint.decode(encoded);
37
- const name = this.getCodecName(codec)
38
- this.name = name
39
- this.encoded = encoded
40
- this.decode(encoded)
41
- }
42
-
43
- fromHex(hex) {
44
- this.encoded = Buffer.from(hex, 'hex')
45
- this.decode()
46
- }
47
-
48
- fromBs32(input) {
49
- this.encoded = bs32.decode(input)
50
- this.decode()
51
- }
52
-
53
- fromBs58(input) {
54
- this.encoded = bs58.decode(input)
55
- this.decode()
56
- }
57
-
58
- getCodec(name) {
59
- return this.codecs[name].codec
60
- }
61
-
62
- getCodecName(codec) {
63
- return Object.keys(this.codecs).reduce((p, c) => {
64
- if (parseInt(Buffer.from(`${this.getCodec(c)}`, 'hex').toString('hex'), 16) === codec) return c;
65
- else return p;
66
- }, undefined)
67
- }
68
-
69
- getHashAlg(name) {
70
- return this.codecs[name].hashAlg
71
- }
72
-
73
- fromCodec(codec) {
74
- this.name = this.getCodecName(codec)
75
- this.hashAlg = this.getHashAlg(this.name)
76
-
77
- this.codec = this.getCodec(this.name)
78
- this.codecBuffer = Buffer.from(varint.encode(parseInt(Buffer.from(`${this.codec}`, 'hex').toString('hex'), 16)), 'hex');
79
- }
80
-
81
- fromName(name) {
82
- const codec = this.getCodec(name)
83
- this.name = name
84
- this.codec = codec
85
- this.hashAlg = this.getHashAlg(name)
86
- this.codecBuffer = Buffer.from(varint.encode(parseInt(Buffer.from(`${codec}`, 'hex').toString('hex'), 16)), 'hex');
87
- }
88
-
89
- toBs32() {
90
- this.encode()
91
- return bs32.encode(this.encoded)
92
- }
93
-
94
- toBs58() {
95
- this.encode()
96
- return bs58.encode(this.encoded)
97
- }
98
-
99
- toHex() {
100
- return this.encoded.toString('hex')
101
- }
102
-
103
- decode() {
104
- const codec = varint.decode(this.encoded);
105
- this.fromCodec(codec)
106
- this.name = this.getCodecName(codec)
107
- }
108
-
109
- encode() {
110
- const codec = Buffer.from(varint.encode(parseInt(Buffer.from(`${this.codec}`, 'hex').toString('hex'), 16)), 'hex');
111
- this.encoded = codec
112
- return this.encoded
113
- }
114
- }
1
+ import varint from 'varint';
2
+ import bs32 from '@vandeurenglenn/base32';
3
+ import bs58 from '@vandeurenglenn/base58';
4
+ import isHex from '@vandeurenglenn/is-hex';
5
+ import codecs from './codecs'
6
+
7
+ export default class PeernetCodec {
8
+ get codecs() {
9
+ return {...globalThis.peernet.codecs, ...codecs}
10
+ }
11
+ constructor(buffer) {
12
+ if (buffer) {
13
+ if (buffer instanceof Uint8Array) {
14
+ const codec = varint.decode(buffer);
15
+ const name = this.getCodecName(codec)
16
+ if (name) {
17
+ this.name = name
18
+ this.encoded = buffer
19
+ this.decode(buffer)
20
+ } else {
21
+ this.encode(buffer)
22
+ }
23
+ } else if (buffer instanceof ArrayBuffer) {
24
+ const encoded = new Uint8Array(buffer.byteLength)
25
+
26
+ for (let i = 0; i < buffer.byteLength; i++) {
27
+ encoded[i] = buffer[i]
28
+ }
29
+ this.encoded = encoded
30
+ // this.encoded = new Uint8Array(buffer, buffer.byteOffset, buffer.byteLength)
31
+ this.decode(buffer)
32
+ return
33
+ }
34
+ if (typeof buffer === 'string') {
35
+ if (this.codecs[buffer]) this.fromName(buffer)
36
+ else if (isHex(buffer)) this.fromHex(buffer)
37
+ else if (bs32.isBase32(buffer)) this.fromBs32(buffer)
38
+ else if (bs58.isBase58(buffer)) this.fromBs58(buffer)
39
+ else throw new Error(`unsupported string ${buffer}`)
40
+ }
41
+ if (!isNaN(buffer)) if (this.codecs[this.getCodecName(buffer)]) this.fromCodec(buffer)
42
+ }
43
+ }
44
+
45
+ fromEncoded(encoded) {
46
+ const codec = varint.decode(encoded);
47
+ const name = this.getCodecName(codec)
48
+ this.name = name
49
+ this.encoded = encoded
50
+ this.decode(encoded)
51
+ }
52
+
53
+ fromHex(hex) {
54
+ this.encoded = Buffer.from(hex, 'hex')
55
+ this.decode()
56
+ }
57
+
58
+ fromBs32(input) {
59
+ this.encoded = bs32.decode(input)
60
+ this.decode()
61
+ }
62
+
63
+ fromBs58(input) {
64
+ this.encoded = bs58.decode(input)
65
+ this.decode()
66
+ }
67
+
68
+ getCodec(name) {
69
+ return this.codecs[name].codec
70
+ }
71
+
72
+ getCodecName(codec) {
73
+ return Object.keys(this.codecs).reduce((p, c) => {
74
+ const item = this.codecs[c]
75
+ if (item.codec === codec) return c;
76
+ else return p;
77
+ }, undefined)
78
+ }
79
+
80
+ getHashAlg(name) {
81
+ return this.codecs[name].hashAlg
82
+ }
83
+
84
+ fromCodec(codec) {
85
+ this.name = this.getCodecName(codec)
86
+ this.hashAlg = this.getHashAlg(this.name)
87
+
88
+ this.codec = this.getCodec(this.name)
89
+ this.codecBuffer = varint.encode(codec)
90
+ }
91
+
92
+ fromName(name) {
93
+ const codec = this.getCodec(name)
94
+ this.name = name
95
+ this.codec = codec
96
+ this.hashAlg = this.getHashAlg(name)
97
+ this.codecBuffer = varint.encode(codec)
98
+ }
99
+
100
+ toBs32() {
101
+ this.encode()
102
+ return bs32.encode(this.encoded)
103
+ }
104
+
105
+ toBs58() {
106
+ this.encode()
107
+ return bs58.encode(this.encoded)
108
+ }
109
+
110
+ toHex() {
111
+ return this.encoded.toString('hex')
112
+ }
113
+
114
+ decode() {
115
+ const codec = varint.decode(this.encoded);
116
+ this.fromCodec(codec)
117
+ }
118
+
119
+ encode() {
120
+ const codec = varint.encode(this.decoded)
121
+ this.encoded = codec
122
+ return this.encoded
123
+ }
124
+ }
@@ -1,79 +1,79 @@
1
- export default {
2
- // just a hash
3
- 'disco-hash': {
4
- codec: '30',
5
- hashAlg: 'dbl-keccak-512', // ,
6
- // testnet: 'olivia'
7
- },
8
- 'peernet-peer-response': {
9
- codec: '707072',
10
- hashAlg: 'keccak-256',
11
- },
12
- 'peernet-peer': {
13
- codec: '7070',
14
- hashAlg: 'keccak-256',
15
- },
16
- 'peernet-dht': {
17
- codec: '706468',
18
- hashAlg: 'keccak-256',
19
- },
20
- 'peernet-dht-response': {
21
- codec: '706472',
22
- hashAlg: 'keccak-256',
23
- },
24
- // data
25
- 'peernet-data': {
26
- codec: '706461',
27
- hashAlg: 'keccak-256',
28
- },
29
- 'peernet-data-response': {
30
- codec: '70646172',
31
- hashAlg: 'keccak-256',
32
- },
33
- // message
34
- 'peernet-message': {
35
- codec: '706d65',
36
- hashAlg: 'keccak-512',
37
- },
38
- // pubsub
39
- 'peernet-ps': {
40
- codec: '707073',
41
- hashAlg: 'keccak-256',
42
- },
43
- 'peernet-response': {
44
- codec: '7072',
45
- hashAlg: 'keccak-256',
46
- },
47
- 'peernet-request': {
48
- codec: '707271',
49
- hashAlg: 'keccak-256',
50
- },
51
- // normal block
52
- 'leofcoin-block': {
53
- codec: '6c62',
54
- hashAlg: 'dbl-keccak-512', // ,
55
- // testnet: 'olivia'
56
- },
57
- 'leofcoin-tx': {
58
- codec: '6c74',
59
- hashAlg: 'dbl-keccak-512', // ,
60
- // testnet: 'olivia'
61
- },
62
- // itx
63
- 'leofcoin-itx': {
64
- codec: '6c69',
65
- hashAlg: 'keccak-512', // ,
66
- // testnet: 'olivia'
67
- },
68
- // peer reputation
69
- 'leofcoin-pr': {
70
- codec: '6c70',
71
- hashAlg: 'keccak-256', // ,
72
- // testnet: 'olivia'
73
- },
74
- // chat message
75
- 'chat-message': {
76
- codec: '636d',
77
- hashAlg: 'dbl-keccak-512',
78
- },
79
- }
1
+ export default {
2
+ // just a hash
3
+ 'disco-hash': {
4
+ codec: parseInt('30', 16),
5
+ hashAlg: 'dbl-keccak-512', // ,
6
+ // testnet: 'olivia'
7
+ },
8
+ 'peernet-peer-response': {
9
+ codec: parseInt('707072', 16),
10
+ hashAlg: 'keccak-256',
11
+ },
12
+ 'peernet-peer': {
13
+ codec: parseInt('7070', 16),
14
+ hashAlg: 'keccak-256',
15
+ },
16
+ 'peernet-dht': {
17
+ codec: parseInt('706468', 16),
18
+ hashAlg: 'keccak-256',
19
+ },
20
+ 'peernet-dht-response': {
21
+ codec: parseInt('706472', 16),
22
+ hashAlg: 'keccak-256',
23
+ },
24
+ // data
25
+ 'peernet-data': {
26
+ codec: parseInt('706461', 16),
27
+ hashAlg: 'keccak-256',
28
+ },
29
+ 'peernet-data-response': {
30
+ codec: parseInt('70646172', 16),
31
+ hashAlg: 'keccak-256',
32
+ },
33
+ // message
34
+ 'peernet-message': {
35
+ codec: parseInt('706d65', 16),
36
+ hashAlg: 'keccak-512',
37
+ },
38
+ // pubsub
39
+ 'peernet-ps': {
40
+ codec: parseInt('707073', 16),
41
+ hashAlg: 'keccak-256',
42
+ },
43
+ 'peernet-response': {
44
+ codec: parseInt('7072', 16),
45
+ hashAlg: 'keccak-256',
46
+ },
47
+ 'peernet-request': {
48
+ codec: parseInt('707271', 16),
49
+ hashAlg: 'keccak-256',
50
+ },
51
+ // normal block
52
+ 'leofcoin-block': {
53
+ codec: parseInt('6c62', 16),
54
+ hashAlg: 'dbl-keccak-512', // ,
55
+ // testnet: 'olivia'
56
+ },
57
+ 'leofcoin-tx': {
58
+ codec: parseInt('6c74', 16),
59
+ hashAlg: 'dbl-keccak-512', // ,
60
+ // testnet: 'olivia'
61
+ },
62
+ // itx
63
+ 'leofcoin-itx': {
64
+ codec: parseInt('6c69', 16),
65
+ hashAlg: 'keccak-512', // ,
66
+ // testnet: 'olivia'
67
+ },
68
+ // peer reputation
69
+ 'leofcoin-pr': {
70
+ codec: parseInt('6c70', 16),
71
+ hashAlg: 'keccak-256', // ,
72
+ // testnet: 'olivia'
73
+ },
74
+ // chat message
75
+ 'chat-message': {
76
+ codec: parseInt('636d', 16),
77
+ hashAlg: 'dbl-keccak-512',
78
+ },
79
+ }
package/src/dht/dht.js CHANGED
@@ -1,121 +1,121 @@
1
- import fetch from 'node-fetch'
2
-
3
- /**
4
- * Keep history of fetched address and ptr
5
- * @property {Object} address
6
- * @property {Object} ptr
7
- */
8
- const lastFetched = {
9
- address: {
10
- value: undefined,
11
- timestamp: 0,
12
- },
13
- ptr: {
14
- value: undefined,
15
- timestamp: 0,
16
- },
17
- }
18
-
19
- const getAddress = async () => {
20
- const {address} = lastFetched
21
- const now = Math.round(new Date().getTime() / 1000);
22
- if (now - address.timestamp > 1200000) {
23
- address.value = await fetch('https://icanhazip.com/')
24
- address.value = await address.value.text()
25
- address.timestamp = Math.round(new Date().getTime() / 1000);
26
- lastFetched.address = address;
27
- }
28
-
29
- return address.value
30
- }
31
-
32
- const degreesToRadians = (degrees) => {
33
- return degrees * Math.PI / 180;
34
- }
35
-
36
- const distanceInKmBetweenEarthCoordinates = (lat1, lon1, lat2, lon2) => {
37
- const earthRadiusKm = 6371;
38
-
39
- const dLat = degreesToRadians(lat2-lat1);
40
- const dLon = degreesToRadians(lon2-lon1);
41
-
42
- lat1 = degreesToRadians(lat1);
43
- lat2 = degreesToRadians(lat2);
44
- const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
45
- Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
46
- const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
47
- return earthRadiusKm * c;
48
- }
49
-
50
- export default class DhtEarth {
51
- /**
52
- *
53
- */
54
- constructor() {
55
- this.providerMap = new Map();
56
- }
57
-
58
- /**
59
- * @param {Object} address
60
- * @return {Object} {latitude: lat, longitude: lon}
61
- */
62
- async getCoordinates(address) {
63
- // const {address} = parseAddress(provider)
64
- const request = `https://whereis.leofcoin.org/?ip=${address}`
65
- let response = await fetch(request)
66
- response = await response.json()
67
- const {lat, lon} = response;
68
- return {latitude: lat, longitude: lon}
69
- }
70
-
71
- /**
72
- * @param {Object} peer
73
- * @param {Object} provider
74
- * @return {Object} {provider, distance}
75
- */
76
- async getDistance(peer, provider) {
77
- const {latitude, longitude} = await this.getCoordinates(provider.address)
78
- return {provider, distance: distanceInKmBetweenEarthCoordinates(peer.latitude, peer.longitude, latitude, longitude)}
79
- }
80
-
81
- /**
82
- * @param {Array} providers
83
- * @return {Object} closestPeer
84
- */
85
- async closestPeer(providers) {
86
- let all = []
87
- const address = await getAddress();
88
- const peerLoc = await this.getCoordinates(address)
89
-
90
- for (const provider of providers) {
91
- if (provider.address === '127.0.0.1') all.push({provider, distance: 0})
92
- else all.push(this.getDistance(peerLoc, provider))
93
- }
94
-
95
- all = await Promise.all(all);
96
- all = all.sort((previous, current) => previous.distance - current.distance)
97
- return all[0].provider;
98
- }
99
-
100
- /**
101
- * @param {String} hash
102
- * @return {Array} providers
103
- */
104
- providersFor(hash) {
105
- return this.providerMap.get(hash);
106
- }
107
-
108
- /**
109
- * @param {String} address
110
- * @param {String} hash
111
- * @return {Array} providers
112
- */
113
- async addProvider(address, hash) {
114
- let providers = [];
115
- if (this.providerMap.has(hash)) providers = this.providerMap.get(hash)
116
-
117
- providers = new Set([...providers, address])
118
- this.providerMap.set(hash, providers)
119
- return providers;
120
- }
121
- }
1
+ import fetch from 'node-fetch'
2
+
3
+ /**
4
+ * Keep history of fetched address and ptr
5
+ * @property {Object} address
6
+ * @property {Object} ptr
7
+ */
8
+ const lastFetched = {
9
+ address: {
10
+ value: undefined,
11
+ timestamp: 0,
12
+ },
13
+ ptr: {
14
+ value: undefined,
15
+ timestamp: 0,
16
+ },
17
+ }
18
+
19
+ const getAddress = async () => {
20
+ const {address} = lastFetched
21
+ const now = Math.round(new Date().getTime() / 1000);
22
+ if (now - address.timestamp > 1200000) {
23
+ address.value = await fetch('https://icanhazip.com/')
24
+ address.value = await address.value.text()
25
+ address.timestamp = Math.round(new Date().getTime() / 1000);
26
+ lastFetched.address = address;
27
+ }
28
+
29
+ return address.value
30
+ }
31
+
32
+ const degreesToRadians = (degrees) => {
33
+ return degrees * Math.PI / 180;
34
+ }
35
+
36
+ const distanceInKmBetweenEarthCoordinates = (lat1, lon1, lat2, lon2) => {
37
+ const earthRadiusKm = 6371;
38
+
39
+ const dLat = degreesToRadians(lat2-lat1);
40
+ const dLon = degreesToRadians(lon2-lon1);
41
+
42
+ lat1 = degreesToRadians(lat1);
43
+ lat2 = degreesToRadians(lat2);
44
+ const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
45
+ Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
46
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
47
+ return earthRadiusKm * c;
48
+ }
49
+
50
+ export default class DhtEarth {
51
+ /**
52
+ *
53
+ */
54
+ constructor() {
55
+ this.providerMap = new Map();
56
+ }
57
+
58
+ /**
59
+ * @param {Object} address
60
+ * @return {Object} {latitude: lat, longitude: lon}
61
+ */
62
+ async getCoordinates(address) {
63
+ // const {address} = parseAddress(provider)
64
+ const request = `https://whereis.leofcoin.org/?ip=${address}`
65
+ let response = await fetch(request)
66
+ response = await response.json()
67
+ const {lat, lon} = response;
68
+ return {latitude: lat, longitude: lon}
69
+ }
70
+
71
+ /**
72
+ * @param {Object} peer
73
+ * @param {Object} provider
74
+ * @return {Object} {provider, distance}
75
+ */
76
+ async getDistance(peer, provider) {
77
+ const {latitude, longitude} = await this.getCoordinates(provider.address)
78
+ return {provider, distance: distanceInKmBetweenEarthCoordinates(peer.latitude, peer.longitude, latitude, longitude)}
79
+ }
80
+
81
+ /**
82
+ * @param {Array} providers
83
+ * @return {Object} closestPeer
84
+ */
85
+ async closestPeer(providers) {
86
+ let all = []
87
+ const address = await getAddress();
88
+ const peerLoc = await this.getCoordinates(address)
89
+
90
+ for (const provider of providers) {
91
+ if (provider.address === '127.0.0.1') all.push({provider, distance: 0})
92
+ else all.push(this.getDistance(peerLoc, provider))
93
+ }
94
+
95
+ all = await Promise.all(all);
96
+ all = all.sort((previous, current) => previous.distance - current.distance)
97
+ return all[0].provider;
98
+ }
99
+
100
+ /**
101
+ * @param {String} hash
102
+ * @return {Array} providers
103
+ */
104
+ providersFor(hash) {
105
+ return this.providerMap.get(hash);
106
+ }
107
+
108
+ /**
109
+ * @param {String} address
110
+ * @param {String} hash
111
+ * @return {Array} providers
112
+ */
113
+ async addProvider(address, hash) {
114
+ let providers = [];
115
+ if (this.providerMap.has(hash)) providers = this.providerMap.get(hash)
116
+
117
+ providers = new Set([...providers, address])
118
+ this.providerMap.set(hash, providers)
119
+ return providers;
120
+ }
121
+ }