@libp2p/utils 0.0.0 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +4 -0
- package/README.md +51 -0
- package/dist/src/address-sort.d.ts +12 -0
- package/dist/src/address-sort.d.ts.map +1 -0
- package/dist/src/address-sort.js +41 -0
- package/dist/src/address-sort.js.map +1 -0
- package/dist/src/array-equals.d.ts +6 -0
- package/dist/src/array-equals.d.ts.map +1 -0
- package/dist/src/array-equals.js +9 -0
- package/dist/src/array-equals.js.map +1 -0
- package/dist/src/ip-port-to-multiaddr.d.ts +11 -0
- package/dist/src/ip-port-to-multiaddr.d.ts.map +1 -0
- package/dist/src/ip-port-to-multiaddr.js +45 -0
- package/dist/src/ip-port-to-multiaddr.js.map +1 -0
- package/dist/src/multiaddr/is-loopback.d.ts +6 -0
- package/dist/src/multiaddr/is-loopback.d.ts.map +1 -0
- package/dist/src/multiaddr/is-loopback.js +10 -0
- package/dist/src/multiaddr/is-loopback.js.map +1 -0
- package/dist/src/multiaddr/is-private.d.ts +6 -0
- package/dist/src/multiaddr/is-private.d.ts.map +1 -0
- package/dist/src/multiaddr/is-private.js +9 -0
- package/dist/src/multiaddr/is-private.js.map +1 -0
- package/dist/src/stream-to-ma-conn.d.ts +38 -0
- package/dist/src/stream-to-ma-conn.d.ts.map +1 -0
- package/dist/src/stream-to-ma-conn.js +51 -0
- package/dist/src/stream-to-ma-conn.js.map +1 -0
- package/package.json +183 -4
- package/src/address-sort.ts +49 -0
- package/src/array-equals.ts +8 -0
- package/src/ip-port-to-multiaddr.ts +49 -0
- package/src/multiaddr/is-loopback.ts +12 -0
- package/src/multiaddr/is-private.ts +11 -0
- package/src/stream-to-ma-conn.ts +92 -0
package/LICENSE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# js-libp2p-utils
|
|
2
|
+
|
|
3
|
+
[](http://protocol.ai)
|
|
4
|
+
[](http://libp2p.io/)
|
|
5
|
+
[](http://webchat.freenode.net/?channels=%23libp2p)
|
|
6
|
+
[](https://discuss.libp2p.io)
|
|
7
|
+
[](https://codecov.io/gh/libp2p/js-libp2p-utils)
|
|
8
|
+
[](https://travis-ci.com/libp2p/js-libp2p-utils)
|
|
9
|
+
[](https://david-dm.org/libp2p/js-libp2p-utils)
|
|
10
|
+
[](https://github.com/feross/standard)
|
|
11
|
+
|
|
12
|
+
> This package serves as a central repository for shared logic and dependencies for all libp2p packages, using `libp2p-utils` helps to easily re-use small scoped blocks of logic across all libp2p modules and also as a dependency proxy (think `aegir` for domain logic dependencies).
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
The libp2p ecosystem has lots of repos with it comes several problems like:
|
|
16
|
+
- Domain logic dedupe - all modules shared a lot of logic like validation, streams handling, etc.
|
|
17
|
+
- Dependencies management - it's really easy with so many repos for dependencies to go out of control, they become outdated, different repos use different modules to do the same thing (like merging defaults options), browser bundles ends up with multiple versions of the same package, bumping versions is cumbersome to do because we need to go through several repos, etc.
|
|
18
|
+
|
|
19
|
+
These problems are the motivation for this package, having shared logic in this package avoids creating cyclic dependencies, centralizes common use modules/functions (exactly like aegir does for the tooling), semantic versioning for 3rd party dependencies is handled in one single place (a good example is going from streams 2 to 3) and maintainers should only care about having `libp2p-utils` updated.
|
|
20
|
+
|
|
21
|
+
## Lead Maintainer
|
|
22
|
+
|
|
23
|
+
[Vasco Santos](https://github.com/vasco-santos)
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
$ npm install --save @libp2p/utils
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
Each function should be imported directly.
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
import ipAndPortToMultiaddr from '@libp2p/utils/ip-port-to-multiaddr'
|
|
37
|
+
|
|
38
|
+
const ma = ipAndPortToMultiaddr('127.0.0.1', 9000)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
You can check the [API docs](./API.md).
|
|
42
|
+
|
|
43
|
+
## Contribute
|
|
44
|
+
|
|
45
|
+
Contributions welcome. Please check out [the issues](https://github.com/libp2p/js-libp2p-utils/issues).
|
|
46
|
+
|
|
47
|
+
Check out our [contributing document](https://github.com/ipfs/community/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to this repo are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).
|
|
48
|
+
|
|
49
|
+
## License
|
|
50
|
+
|
|
51
|
+
[MIT](LICENSE) © Protocol Labs Inc.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Multiaddr } from '@multiformats/multiaddr';
|
|
2
|
+
interface Address {
|
|
3
|
+
multiaddr: Multiaddr;
|
|
4
|
+
isCertified: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Sort given addresses by putting public addresses first.
|
|
8
|
+
* In case of equality, a certified address will come first.
|
|
9
|
+
*/
|
|
10
|
+
export declare function publicAddressesFirst(addresses: Address[]): Address[];
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=address-sort.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address-sort.d.ts","sourceRoot":"","sources":["../../src/address-sort.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAGxD,UAAU,OAAO;IACf,SAAS,EAAE,SAAS,CAAA;IACpB,WAAW,EAAE,OAAO,CAAA;CACrB;AAoCD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAE,SAAS,EAAE,OAAO,EAAE,aAEzD"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { isPrivate } from './multiaddr/is-private.js';
|
|
2
|
+
/**
|
|
3
|
+
* @typedef {Object} Address
|
|
4
|
+
* @property {Multiaddr} multiaddr peer multiaddr.
|
|
5
|
+
* @property {boolean} isCertified obtained from a signed peer record.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Compare function for array.sort().
|
|
9
|
+
* This sort aims to move the private adresses to the end of the array.
|
|
10
|
+
* In case of equality, a certified address will come first.
|
|
11
|
+
*
|
|
12
|
+
* @param {Address} a
|
|
13
|
+
* @param {Address} b
|
|
14
|
+
* @returns {number}
|
|
15
|
+
*/
|
|
16
|
+
function addressesPublicFirstCompareFunction(a, b) {
|
|
17
|
+
const isAPrivate = isPrivate(a.multiaddr);
|
|
18
|
+
const isBPrivate = isPrivate(b.multiaddr);
|
|
19
|
+
if (isAPrivate && !isBPrivate) {
|
|
20
|
+
return 1;
|
|
21
|
+
}
|
|
22
|
+
else if (!isAPrivate && isBPrivate) {
|
|
23
|
+
return -1;
|
|
24
|
+
}
|
|
25
|
+
// Check certified?
|
|
26
|
+
if (a.isCertified && !b.isCertified) {
|
|
27
|
+
return -1;
|
|
28
|
+
}
|
|
29
|
+
else if (!a.isCertified && b.isCertified) {
|
|
30
|
+
return 1;
|
|
31
|
+
}
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Sort given addresses by putting public addresses first.
|
|
36
|
+
* In case of equality, a certified address will come first.
|
|
37
|
+
*/
|
|
38
|
+
export function publicAddressesFirst(addresses) {
|
|
39
|
+
return [...addresses].sort(addressesPublicFirstCompareFunction);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=address-sort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address-sort.js","sourceRoot":"","sources":["../../src/address-sort.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAOrD;;;;GAIG;AAEH;;;;;;;;GAQG;AACH,SAAS,mCAAmC,CAAE,CAAU,EAAE,CAAU;IAClE,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IACzC,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IAEzC,IAAI,UAAU,IAAI,CAAC,UAAU,EAAE;QAC7B,OAAO,CAAC,CAAA;KACT;SAAM,IAAI,CAAC,UAAU,IAAI,UAAU,EAAE;QACpC,OAAO,CAAC,CAAC,CAAA;KACV;IACD,mBAAmB;IACnB,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE;QACnC,OAAO,CAAC,CAAC,CAAA;KACV;SAAM,IAAI,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW,EAAE;QAC1C,OAAO,CAAC,CAAA;KACT;IAED,OAAO,CAAC,CAAA;AACV,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAE,SAAoB;IACxD,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAA;AACjE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array-equals.d.ts","sourceRoot":"","sources":["../../src/array-equals.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,WAAW,CAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,WAG9C"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verify if two arrays of non primitive types with the "equals" function are equal.
|
|
3
|
+
* Compatible with multiaddr, peer-id and others.
|
|
4
|
+
*/
|
|
5
|
+
export function arrayEquals(a, b) {
|
|
6
|
+
const sort = (a, b) => a.toString().localeCompare(b.toString());
|
|
7
|
+
return a.length === b.length && b.sort(sort) && a.sort(sort).every((item, index) => b[index].equals(item));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=array-equals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"array-equals.js","sourceRoot":"","sources":["../../src/array-equals.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAE,CAAQ,EAAE,CAAQ;IAC7C,MAAM,IAAI,GAAG,CAAC,CAAM,EAAE,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;IACzE,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;AAC5G,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Multiaddr } from '@multiformats/multiaddr';
|
|
2
|
+
export declare const Errors: {
|
|
3
|
+
ERR_INVALID_IP_PARAMETER: string;
|
|
4
|
+
ERR_INVALID_PORT_PARAMETER: string;
|
|
5
|
+
ERR_INVALID_IP: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Transform an IP, Port pair into a multiaddr
|
|
9
|
+
*/
|
|
10
|
+
export declare function ipPortToMultiaddr(ip: string, port: number | string): Multiaddr;
|
|
11
|
+
//# sourceMappingURL=ip-port-to-multiaddr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-port-to-multiaddr.d.ts","sourceRoot":"","sources":["../../src/ip-port-to-multiaddr.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAQnD,eAAO,MAAM,MAAM;;;;CAIlB,CAAA;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,aA8BnE"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import debug from 'debug';
|
|
2
|
+
import { Multiaddr } from '@multiformats/multiaddr';
|
|
3
|
+
import errCode from 'err-code';
|
|
4
|
+
import { Address4, Address6 } from '@achingbrain/ip-address';
|
|
5
|
+
const log = Object.assign(debug('libp2p:ip-port-to-multiaddr'), {
|
|
6
|
+
error: debug('libp2p:ip-port-to-multiaddr:err')
|
|
7
|
+
});
|
|
8
|
+
export const Errors = {
|
|
9
|
+
ERR_INVALID_IP_PARAMETER: 'ERR_INVALID_IP_PARAMETER',
|
|
10
|
+
ERR_INVALID_PORT_PARAMETER: 'ERR_INVALID_PORT_PARAMETER',
|
|
11
|
+
ERR_INVALID_IP: 'ERR_INVALID_IP'
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Transform an IP, Port pair into a multiaddr
|
|
15
|
+
*/
|
|
16
|
+
export function ipPortToMultiaddr(ip, port) {
|
|
17
|
+
if (typeof ip !== 'string') {
|
|
18
|
+
throw errCode(new Error(`invalid ip provided: ${ip}`), Errors.ERR_INVALID_IP_PARAMETER); // eslint-disable-line @typescript-eslint/restrict-template-expressions
|
|
19
|
+
}
|
|
20
|
+
if (typeof port === 'string') {
|
|
21
|
+
port = parseInt(port);
|
|
22
|
+
}
|
|
23
|
+
if (isNaN(port)) {
|
|
24
|
+
throw errCode(new Error(`invalid port provided: ${port}`), Errors.ERR_INVALID_PORT_PARAMETER);
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
// Test valid IPv4
|
|
28
|
+
new Address4(ip); // eslint-disable-line no-new
|
|
29
|
+
return new Multiaddr(`/ip4/${ip}/tcp/${port}`);
|
|
30
|
+
}
|
|
31
|
+
catch { }
|
|
32
|
+
try {
|
|
33
|
+
// Test valid IPv6
|
|
34
|
+
const ip6 = new Address6(ip);
|
|
35
|
+
return ip6.is4()
|
|
36
|
+
? new Multiaddr(`/ip4/${ip6.to4().correctForm()}/tcp/${port}`)
|
|
37
|
+
: new Multiaddr(`/ip6/${ip}/tcp/${port}`);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
const errMsg = `invalid ip:port for creating a multiaddr: ${ip}:${port}`;
|
|
41
|
+
log.error(errMsg);
|
|
42
|
+
throw errCode(new Error(errMsg), Errors.ERR_INVALID_IP);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=ip-port-to-multiaddr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-port-to-multiaddr.js","sourceRoot":"","sources":["../../src/ip-port-to-multiaddr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACnD,OAAO,OAAO,MAAM,UAAU,CAAA;AAC9B,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAE5D,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,CAAC,EAAE;IAC9D,KAAK,EAAE,KAAK,CAAC,iCAAiC,CAAC;CAChD,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,wBAAwB,EAAE,0BAA0B;IACpD,0BAA0B,EAAE,4BAA4B;IACxD,cAAc,EAAE,gBAAgB;CACjC,CAAA;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAE,EAAU,EAAE,IAAqB;IAClE,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE;QAC1B,MAAM,OAAO,CAAC,IAAI,KAAK,CAAC,wBAAwB,EAAE,EAAE,CAAC,EAAE,MAAM,CAAC,wBAAwB,CAAC,CAAA,CAAC,uEAAuE;KAChK;IAED,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;QAC5B,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;KACtB;IAED,IAAI,KAAK,CAAC,IAAI,CAAC,EAAE;QACf,MAAM,OAAO,CAAC,IAAI,KAAK,CAAC,0BAA0B,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,0BAA0B,CAAC,CAAA;KAC9F;IAED,IAAI;QACF,kBAAkB;QAClB,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAA,CAAC,6BAA6B;QAC9C,OAAO,IAAI,SAAS,CAAC,QAAQ,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAA;KAC/C;IAAC,MAAM,GAAE;IAEV,IAAI;QACF,kBAAkB;QAClB,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAA;QAC5B,OAAO,GAAG,CAAC,GAAG,EAAE;YACd,CAAC,CAAC,IAAI,SAAS,CAAC,QAAQ,GAAG,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,QAAQ,IAAI,EAAE,CAAC;YAC9D,CAAC,CAAC,IAAI,SAAS,CAAC,QAAQ,EAAE,QAAQ,IAAI,EAAE,CAAC,CAAA;KAC5C;IAAC,OAAO,GAAG,EAAE;QACZ,MAAM,MAAM,GAAG,6CAA6C,EAAE,IAAI,IAAI,EAAE,CAAA;QACxE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QACjB,MAAM,OAAO,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC,CAAA;KACxD;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-loopback.d.ts","sourceRoot":"","sources":["../../../src/multiaddr/is-loopback.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAExD;;GAEG;AACH,wBAAgB,UAAU,CAAE,EAAE,EAAE,SAAS,OAIxC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// @ts-expect-error is-loopback-addr does not publish types
|
|
2
|
+
import isLoopbackAddr from 'is-loopback-addr';
|
|
3
|
+
/**
|
|
4
|
+
* Check if a given multiaddr is a loopback address.
|
|
5
|
+
*/
|
|
6
|
+
export function isLoopback(ma) {
|
|
7
|
+
const { address } = ma.nodeAddress();
|
|
8
|
+
return isLoopbackAddr(address);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=is-loopback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-loopback.js","sourceRoot":"","sources":["../../../src/multiaddr/is-loopback.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,OAAO,cAAc,MAAM,kBAAkB,CAAA;AAG7C;;GAEG;AACH,MAAM,UAAU,UAAU,CAAE,EAAa;IACvC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE,CAAA;IAEpC,OAAO,cAAc,CAAC,OAAO,CAAC,CAAA;AAChC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-private.d.ts","sourceRoot":"","sources":["../../../src/multiaddr/is-private.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAGxD;;GAEG;AACH,wBAAgB,SAAS,CAAE,EAAE,EAAE,SAAS,WAIvC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is-private.js","sourceRoot":"","sources":["../../../src/multiaddr/is-private.ts"],"names":[],"mappings":"AACA,OAAO,WAAW,MAAM,YAAY,CAAA;AAEpC;;GAEG;AACH,MAAM,UAAU,SAAS,CAAE,EAAa;IACtC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE,CAAA;IAEpC,OAAO,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAA;AACtC,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { MuxedStream } from '@libp2p/interfaces/stream-muxer';
|
|
2
|
+
import type { Multiaddr } from '@multiformats/multiaddr';
|
|
3
|
+
import type { MultiaddrConnection } from '@libp2p/interfaces/transport';
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {Object} Timeline
|
|
6
|
+
* @property {number} open -
|
|
7
|
+
* @property {number} [upgraded] - .
|
|
8
|
+
* @property {number} [close]
|
|
9
|
+
*/
|
|
10
|
+
export interface Timeline {
|
|
11
|
+
/**
|
|
12
|
+
* Connection opening timestamp
|
|
13
|
+
*/
|
|
14
|
+
open: number;
|
|
15
|
+
/**
|
|
16
|
+
* Connection upgraded timestamp
|
|
17
|
+
*/
|
|
18
|
+
upgraded?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Connection closed timestamp
|
|
21
|
+
*/
|
|
22
|
+
close?: number;
|
|
23
|
+
}
|
|
24
|
+
interface StreamOptions {
|
|
25
|
+
signal?: AbortSignal;
|
|
26
|
+
}
|
|
27
|
+
interface StreamProperties {
|
|
28
|
+
stream: MuxedStream<Uint8Array>;
|
|
29
|
+
remoteAddr: Multiaddr;
|
|
30
|
+
localAddr: Multiaddr;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Convert a duplex iterable into a MultiaddrConnection.
|
|
34
|
+
* https://github.com/libp2p/interface-transport#multiaddrconnection
|
|
35
|
+
*/
|
|
36
|
+
export declare function streamToMaConnection(props: StreamProperties, options?: StreamOptions): MultiaddrConnection<Uint8Array>;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=stream-to-ma-conn.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-to-ma-conn.d.ts","sourceRoot":"","sources":["../../src/stream-to-ma-conn.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA;AAIvE;;;;;GAKG;AAEH,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IAEZ;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,UAAU,aAAa;IACrB,MAAM,CAAC,EAAE,WAAW,CAAA;CAErB;AAED,UAAU,gBAAgB;IACxB,MAAM,EAAE,WAAW,CAAC,UAAU,CAAC,CAAA;IAC/B,UAAU,EAAE,SAAS,CAAA;IACrB,SAAS,EAAE,SAAS,CAAA;CACrB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAE,KAAK,EAAE,gBAAgB,EAAE,OAAO,GAAE,aAAkB,mCA4CzF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { source as abortable } from 'abortable-iterator';
|
|
2
|
+
import debug from 'debug';
|
|
3
|
+
const log = debug('libp2p:stream:converter');
|
|
4
|
+
/**
|
|
5
|
+
* Convert a duplex iterable into a MultiaddrConnection.
|
|
6
|
+
* https://github.com/libp2p/interface-transport#multiaddrconnection
|
|
7
|
+
*/
|
|
8
|
+
export function streamToMaConnection(props, options = {}) {
|
|
9
|
+
const { stream, remoteAddr, localAddr } = props;
|
|
10
|
+
const { sink, source } = stream;
|
|
11
|
+
const maConn = {
|
|
12
|
+
async sink(source) {
|
|
13
|
+
if (options.signal != null) {
|
|
14
|
+
source = abortable(source, options.signal);
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
await sink(source);
|
|
18
|
+
await close();
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
// If aborted we can safely ignore
|
|
22
|
+
if (err.type !== 'aborted') {
|
|
23
|
+
// If the source errored the socket will already have been destroyed by
|
|
24
|
+
// toIterable.duplex(). If the socket errored it will already be
|
|
25
|
+
// destroyed. There's nothing to do here except log the error & return.
|
|
26
|
+
log(err);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
source: (options.signal != null) ? abortable(source, options.signal) : source,
|
|
31
|
+
conn: stream,
|
|
32
|
+
localAddr,
|
|
33
|
+
remoteAddr,
|
|
34
|
+
/** @type {Timeline} */
|
|
35
|
+
timeline: { open: Date.now(), close: undefined },
|
|
36
|
+
async close() {
|
|
37
|
+
await sink(async function* () {
|
|
38
|
+
yield new Uint8Array(0);
|
|
39
|
+
}());
|
|
40
|
+
await close();
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
async function close() {
|
|
44
|
+
if (maConn.timeline.close == null) {
|
|
45
|
+
maConn.timeline.close = Date.now();
|
|
46
|
+
}
|
|
47
|
+
return await Promise.resolve();
|
|
48
|
+
}
|
|
49
|
+
return maConn;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=stream-to-ma-conn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-to-ma-conn.js","sourceRoot":"","sources":["../../src/stream-to-ma-conn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,MAAM,OAAO,CAAA;AAKzB,MAAM,GAAG,GAAG,KAAK,CAAC,yBAAyB,CAAC,CAAA;AAqC5C;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAE,KAAuB,EAAE,UAAyB,EAAE;IACxF,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,KAAK,CAAA;IAC/C,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;IAC/B,MAAM,MAAM,GAAwB;QAClC,KAAK,CAAC,IAAI,CAAE,MAAM;YAChB,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI,EAAE;gBAC1B,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;aAC3C;YAED,IAAI;gBACF,MAAM,IAAI,CAAC,MAAM,CAAC,CAAA;gBAClB,MAAM,KAAK,EAAE,CAAA;aACd;YAAC,OAAO,GAAQ,EAAE;gBACjB,kCAAkC;gBAClC,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE;oBAC1B,uEAAuE;oBACvE,gEAAgE;oBAChE,uEAAuE;oBACvE,GAAG,CAAC,GAAG,CAAC,CAAA;iBACT;aACF;QACH,CAAC;QACD,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM;QAC7E,IAAI,EAAE,MAAM;QACZ,SAAS;QACT,UAAU;QACV,uBAAuB;QACvB,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;QAChD,KAAK,CAAC,KAAK;YACT,MAAM,IAAI,CAAC,KAAK,SAAU,CAAC;gBACzB,MAAM,IAAI,UAAU,CAAC,CAAC,CAAC,CAAA;YACzB,CAAC,EAAE,CAAC,CAAA;YACJ,MAAM,KAAK,EAAE,CAAA;QACf,CAAC;KACF,CAAA;IAED,KAAK,UAAU,KAAK;QAClB,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAI,EAAE;YACjC,MAAM,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;SACnC;QACD,OAAO,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;IAChC,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,186 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libp2p/utils",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "",
|
|
5
|
-
"
|
|
6
|
-
"license": "
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"description": "Package to aggregate shared logic and dependencies for the libp2p ecosystem",
|
|
5
|
+
"homepage": "https://github.com/libp2p/js-libp2p-utils#readme",
|
|
6
|
+
"license": "Apache-2.0 OR MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/libp2p/js-libp2p-utils.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/libp2p/js-libp2p-utils/issues"
|
|
13
|
+
},
|
|
14
|
+
"type": "module",
|
|
15
|
+
"types": "./dist/src/index.d.ts",
|
|
16
|
+
"typesVersions": {
|
|
17
|
+
"*": {
|
|
18
|
+
"*": [
|
|
19
|
+
"*",
|
|
20
|
+
"dist/*",
|
|
21
|
+
"dist/src/*",
|
|
22
|
+
"dist/src/*/index"
|
|
23
|
+
],
|
|
24
|
+
"src/*": [
|
|
25
|
+
"*",
|
|
26
|
+
"dist/*",
|
|
27
|
+
"dist/src/*",
|
|
28
|
+
"dist/src/*/index"
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"src",
|
|
34
|
+
"dist/src",
|
|
35
|
+
"!dist/test",
|
|
36
|
+
"!**/*.tsbuildinfo"
|
|
37
|
+
],
|
|
38
|
+
"exports": {
|
|
39
|
+
".": {
|
|
40
|
+
"import": "./dist/src/index.js"
|
|
41
|
+
},
|
|
42
|
+
"./multiaddr/is-loopback": {
|
|
43
|
+
"import": "./dist/src/multiaddr/is-loopback.js",
|
|
44
|
+
"types": "./dist/src/multiaddr/is-loopback.d.ts"
|
|
45
|
+
},
|
|
46
|
+
"./multiaddr/is-private": {
|
|
47
|
+
"import": "./dist/src/multiaddr/is-private.js",
|
|
48
|
+
"types": "./dist/src/multiaddr/is-private.d.ts"
|
|
49
|
+
},
|
|
50
|
+
"./address-sort": {
|
|
51
|
+
"import": "./dist/src/address-sort.js",
|
|
52
|
+
"types": "./dist/src/address-sort.d.ts"
|
|
53
|
+
},
|
|
54
|
+
"./array-equals": {
|
|
55
|
+
"import": "./dist/src/array-equals.js",
|
|
56
|
+
"types": "./dist/src/array-equals.d.ts"
|
|
57
|
+
},
|
|
58
|
+
"./ip-port-to-multiaddr": {
|
|
59
|
+
"import": "./dist/src/ip-port-to-multiaddr.js",
|
|
60
|
+
"types": "./dist/src/ip-port-to-multiaddr.d.ts"
|
|
61
|
+
},
|
|
62
|
+
"./stream-to-ma-conn": {
|
|
63
|
+
"import": "./dist/src/stream-to-ma-connr.js",
|
|
64
|
+
"types": "./dist/src/stream-to-ma-connr.d.ts"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"eslintConfig": {
|
|
68
|
+
"extends": "ipfs",
|
|
69
|
+
"parserOptions": {
|
|
70
|
+
"sourceType": "module"
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"release": {
|
|
74
|
+
"branches": [
|
|
75
|
+
"master"
|
|
76
|
+
],
|
|
77
|
+
"plugins": [
|
|
78
|
+
[
|
|
79
|
+
"@semantic-release/commit-analyzer",
|
|
80
|
+
{
|
|
81
|
+
"preset": "conventionalcommits",
|
|
82
|
+
"releaseRules": [
|
|
83
|
+
{
|
|
84
|
+
"breaking": true,
|
|
85
|
+
"release": "major"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"revert": true,
|
|
89
|
+
"release": "patch"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"type": "feat",
|
|
93
|
+
"release": "minor"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"type": "fix",
|
|
97
|
+
"release": "patch"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"type": "chore",
|
|
101
|
+
"release": "patch"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"type": "docs",
|
|
105
|
+
"release": "patch"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"type": "test",
|
|
109
|
+
"release": "patch"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"scope": "no-release",
|
|
113
|
+
"release": false
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
],
|
|
118
|
+
[
|
|
119
|
+
"@semantic-release/release-notes-generator",
|
|
120
|
+
{
|
|
121
|
+
"preset": "conventionalcommits",
|
|
122
|
+
"presetConfig": {
|
|
123
|
+
"types": [
|
|
124
|
+
{
|
|
125
|
+
"type": "feat",
|
|
126
|
+
"section": "Features"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"type": "fix",
|
|
130
|
+
"section": "Bug Fixes"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"type": "chore",
|
|
134
|
+
"section": "Trivial Changes"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"type": "docs",
|
|
138
|
+
"section": "Trivial Changes"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"type": "test",
|
|
142
|
+
"section": "Tests"
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
],
|
|
148
|
+
"@semantic-release/changelog",
|
|
149
|
+
"@semantic-release/npm",
|
|
150
|
+
"@semantic-release/github",
|
|
151
|
+
"@semantic-release/git"
|
|
152
|
+
]
|
|
153
|
+
},
|
|
154
|
+
"scripts": {
|
|
155
|
+
"lint": "aegir lint",
|
|
156
|
+
"dep-check": "aegir dep-check dist/src/**/*.js dist/test/**/*.js",
|
|
157
|
+
"build": "tsc",
|
|
158
|
+
"pretest": "npm run build",
|
|
159
|
+
"test": "aegir test -f ./dist/test/**/*.js",
|
|
160
|
+
"test:chrome": "npm run test -- -t browser",
|
|
161
|
+
"test:chrome-webworker": "npm run test -- -t webworker",
|
|
162
|
+
"test:firefox": "npm run test -- -t browser -- --browser firefox",
|
|
163
|
+
"test:firefox-webworker": "npm run test -- -t webworker -- --browser firefox",
|
|
164
|
+
"test:node": "npm run test -- -t node --cov",
|
|
165
|
+
"test:electron-main": "npm run test -- -t electron-main",
|
|
166
|
+
"release": "semantic-release"
|
|
167
|
+
},
|
|
168
|
+
"dependencies": {
|
|
169
|
+
"@achingbrain/ip-address": "^8.1.0",
|
|
170
|
+
"@multiformats/multiaddr": "^10.1.1",
|
|
171
|
+
"abortable-iterator": "^3.0.0",
|
|
172
|
+
"debug": "^4.3.0",
|
|
173
|
+
"err-code": "^3.0.1",
|
|
174
|
+
"is-loopback-addr": "^1.0.0",
|
|
175
|
+
"private-ip": "^2.1.1"
|
|
176
|
+
},
|
|
177
|
+
"devDependencies": {
|
|
178
|
+
"@libp2p/interfaces": "^0.2.0",
|
|
179
|
+
"@types/debug": "^4.1.5",
|
|
180
|
+
"aegir": "^36.1.2",
|
|
181
|
+
"it-pair": "^1.0.0",
|
|
182
|
+
"it-pipe": "^1.1.0",
|
|
183
|
+
"streaming-iterables": "^6.0.0",
|
|
184
|
+
"util": "^0.12.3"
|
|
185
|
+
}
|
|
7
186
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
2
|
+
import { isPrivate } from './multiaddr/is-private.js'
|
|
3
|
+
|
|
4
|
+
interface Address {
|
|
5
|
+
multiaddr: Multiaddr
|
|
6
|
+
isCertified: boolean
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {Object} Address
|
|
11
|
+
* @property {Multiaddr} multiaddr peer multiaddr.
|
|
12
|
+
* @property {boolean} isCertified obtained from a signed peer record.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Compare function for array.sort().
|
|
17
|
+
* This sort aims to move the private adresses to the end of the array.
|
|
18
|
+
* In case of equality, a certified address will come first.
|
|
19
|
+
*
|
|
20
|
+
* @param {Address} a
|
|
21
|
+
* @param {Address} b
|
|
22
|
+
* @returns {number}
|
|
23
|
+
*/
|
|
24
|
+
function addressesPublicFirstCompareFunction (a: Address, b: Address) {
|
|
25
|
+
const isAPrivate = isPrivate(a.multiaddr)
|
|
26
|
+
const isBPrivate = isPrivate(b.multiaddr)
|
|
27
|
+
|
|
28
|
+
if (isAPrivate && !isBPrivate) {
|
|
29
|
+
return 1
|
|
30
|
+
} else if (!isAPrivate && isBPrivate) {
|
|
31
|
+
return -1
|
|
32
|
+
}
|
|
33
|
+
// Check certified?
|
|
34
|
+
if (a.isCertified && !b.isCertified) {
|
|
35
|
+
return -1
|
|
36
|
+
} else if (!a.isCertified && b.isCertified) {
|
|
37
|
+
return 1
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return 0
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Sort given addresses by putting public addresses first.
|
|
45
|
+
* In case of equality, a certified address will come first.
|
|
46
|
+
*/
|
|
47
|
+
export function publicAddressesFirst (addresses: Address[]) {
|
|
48
|
+
return [...addresses].sort(addressesPublicFirstCompareFunction)
|
|
49
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verify if two arrays of non primitive types with the "equals" function are equal.
|
|
3
|
+
* Compatible with multiaddr, peer-id and others.
|
|
4
|
+
*/
|
|
5
|
+
export function arrayEquals (a: any[], b: any[]) {
|
|
6
|
+
const sort = (a: any, b: any) => a.toString().localeCompare(b.toString())
|
|
7
|
+
return a.length === b.length && b.sort(sort) && a.sort(sort).every((item, index) => b[index].equals(item))
|
|
8
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import debug from 'debug'
|
|
2
|
+
import { Multiaddr } from '@multiformats/multiaddr'
|
|
3
|
+
import errCode from 'err-code'
|
|
4
|
+
import { Address4, Address6 } from '@achingbrain/ip-address'
|
|
5
|
+
|
|
6
|
+
const log = Object.assign(debug('libp2p:ip-port-to-multiaddr'), {
|
|
7
|
+
error: debug('libp2p:ip-port-to-multiaddr:err')
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
export const Errors = {
|
|
11
|
+
ERR_INVALID_IP_PARAMETER: 'ERR_INVALID_IP_PARAMETER',
|
|
12
|
+
ERR_INVALID_PORT_PARAMETER: 'ERR_INVALID_PORT_PARAMETER',
|
|
13
|
+
ERR_INVALID_IP: 'ERR_INVALID_IP'
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Transform an IP, Port pair into a multiaddr
|
|
18
|
+
*/
|
|
19
|
+
export function ipPortToMultiaddr (ip: string, port: number | string) {
|
|
20
|
+
if (typeof ip !== 'string') {
|
|
21
|
+
throw errCode(new Error(`invalid ip provided: ${ip}`), Errors.ERR_INVALID_IP_PARAMETER) // eslint-disable-line @typescript-eslint/restrict-template-expressions
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (typeof port === 'string') {
|
|
25
|
+
port = parseInt(port)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (isNaN(port)) {
|
|
29
|
+
throw errCode(new Error(`invalid port provided: ${port}`), Errors.ERR_INVALID_PORT_PARAMETER)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
// Test valid IPv4
|
|
34
|
+
new Address4(ip) // eslint-disable-line no-new
|
|
35
|
+
return new Multiaddr(`/ip4/${ip}/tcp/${port}`)
|
|
36
|
+
} catch {}
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
// Test valid IPv6
|
|
40
|
+
const ip6 = new Address6(ip)
|
|
41
|
+
return ip6.is4()
|
|
42
|
+
? new Multiaddr(`/ip4/${ip6.to4().correctForm()}/tcp/${port}`)
|
|
43
|
+
: new Multiaddr(`/ip6/${ip}/tcp/${port}`)
|
|
44
|
+
} catch (err) {
|
|
45
|
+
const errMsg = `invalid ip:port for creating a multiaddr: ${ip}:${port}`
|
|
46
|
+
log.error(errMsg)
|
|
47
|
+
throw errCode(new Error(errMsg), Errors.ERR_INVALID_IP)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// @ts-expect-error is-loopback-addr does not publish types
|
|
2
|
+
import isLoopbackAddr from 'is-loopback-addr'
|
|
3
|
+
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Check if a given multiaddr is a loopback address.
|
|
7
|
+
*/
|
|
8
|
+
export function isLoopback (ma: Multiaddr) {
|
|
9
|
+
const { address } = ma.nodeAddress()
|
|
10
|
+
|
|
11
|
+
return isLoopbackAddr(address)
|
|
12
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
2
|
+
import isIpPrivate from 'private-ip'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Check if a given multiaddr has a private address.
|
|
6
|
+
*/
|
|
7
|
+
export function isPrivate (ma: Multiaddr) {
|
|
8
|
+
const { address } = ma.nodeAddress()
|
|
9
|
+
|
|
10
|
+
return Boolean(isIpPrivate(address))
|
|
11
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { source as abortable } from 'abortable-iterator'
|
|
2
|
+
import debug from 'debug'
|
|
3
|
+
import type { MuxedStream } from '@libp2p/interfaces/stream-muxer'
|
|
4
|
+
import type { Multiaddr } from '@multiformats/multiaddr'
|
|
5
|
+
import type { MultiaddrConnection } from '@libp2p/interfaces/transport'
|
|
6
|
+
|
|
7
|
+
const log = debug('libp2p:stream:converter')
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {Object} Timeline
|
|
11
|
+
* @property {number} open -
|
|
12
|
+
* @property {number} [upgraded] - .
|
|
13
|
+
* @property {number} [close]
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export interface Timeline {
|
|
17
|
+
/**
|
|
18
|
+
* Connection opening timestamp
|
|
19
|
+
*/
|
|
20
|
+
open: number
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Connection upgraded timestamp
|
|
24
|
+
*/
|
|
25
|
+
upgraded?: number
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Connection closed timestamp
|
|
29
|
+
*/
|
|
30
|
+
close?: number
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface StreamOptions {
|
|
34
|
+
signal?: AbortSignal
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface StreamProperties {
|
|
39
|
+
stream: MuxedStream<Uint8Array>
|
|
40
|
+
remoteAddr: Multiaddr
|
|
41
|
+
localAddr: Multiaddr
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Convert a duplex iterable into a MultiaddrConnection.
|
|
46
|
+
* https://github.com/libp2p/interface-transport#multiaddrconnection
|
|
47
|
+
*/
|
|
48
|
+
export function streamToMaConnection (props: StreamProperties, options: StreamOptions = {}) {
|
|
49
|
+
const { stream, remoteAddr, localAddr } = props
|
|
50
|
+
const { sink, source } = stream
|
|
51
|
+
const maConn: MultiaddrConnection = {
|
|
52
|
+
async sink (source) {
|
|
53
|
+
if (options.signal != null) {
|
|
54
|
+
source = abortable(source, options.signal)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
await sink(source)
|
|
59
|
+
await close()
|
|
60
|
+
} catch (err: any) {
|
|
61
|
+
// If aborted we can safely ignore
|
|
62
|
+
if (err.type !== 'aborted') {
|
|
63
|
+
// If the source errored the socket will already have been destroyed by
|
|
64
|
+
// toIterable.duplex(). If the socket errored it will already be
|
|
65
|
+
// destroyed. There's nothing to do here except log the error & return.
|
|
66
|
+
log(err)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
source: (options.signal != null) ? abortable(source, options.signal) : source,
|
|
71
|
+
conn: stream,
|
|
72
|
+
localAddr,
|
|
73
|
+
remoteAddr,
|
|
74
|
+
/** @type {Timeline} */
|
|
75
|
+
timeline: { open: Date.now(), close: undefined },
|
|
76
|
+
async close () {
|
|
77
|
+
await sink(async function * () {
|
|
78
|
+
yield new Uint8Array(0)
|
|
79
|
+
}())
|
|
80
|
+
await close()
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function close () {
|
|
85
|
+
if (maConn.timeline.close == null) {
|
|
86
|
+
maConn.timeline.close = Date.now()
|
|
87
|
+
}
|
|
88
|
+
return await Promise.resolve()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return maConn
|
|
92
|
+
}
|