@libp2p/peer-id 0.0.0 → 0.2.0
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 +42 -0
- package/dist/src/index.d.ts +63 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +145 -0
- package/dist/src/index.js.map +1 -0
- package/package.json +54 -4
- package/src/index.ts +201 -0
package/LICENSE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# libp2p-peer-id <!-- omit in toc -->
|
|
2
|
+
|
|
3
|
+
> peer-ids in JavaScript
|
|
4
|
+
|
|
5
|
+
## Table of Contents <!-- omit in toc -->
|
|
6
|
+
|
|
7
|
+
- [Description](#description)
|
|
8
|
+
- [Example](#example)
|
|
9
|
+
- [Installation](#installation)
|
|
10
|
+
- [License](#license)
|
|
11
|
+
- [Contribution](#contribution)
|
|
12
|
+
|
|
13
|
+
# Description
|
|
14
|
+
|
|
15
|
+
A basic implementation of a peer id
|
|
16
|
+
|
|
17
|
+
# Example
|
|
18
|
+
|
|
19
|
+
```JavaScript
|
|
20
|
+
import { PeerId } from '@libp2p/peer-id'
|
|
21
|
+
|
|
22
|
+
const id = new PeerId(...)
|
|
23
|
+
|
|
24
|
+
console.log(id.toCid())
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
# Installation
|
|
28
|
+
|
|
29
|
+
```console
|
|
30
|
+
$ npm i libp2p-peer-id
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## License
|
|
34
|
+
|
|
35
|
+
Licensed under either of
|
|
36
|
+
|
|
37
|
+
* Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / http://www.apache.org/licenses/LICENSE-2.0)
|
|
38
|
+
* MIT ([LICENSE-MIT](LICENSE-MIT) / http://opensource.org/licenses/MIT)
|
|
39
|
+
|
|
40
|
+
### Contribution
|
|
41
|
+
|
|
42
|
+
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { CID } from 'multiformats/cid';
|
|
2
|
+
import type { MultibaseDecoder, MultibaseEncoder } from 'multiformats/types/bases/interface';
|
|
3
|
+
import type { MultihashDigest } from 'multiformats/types/hashes/interface';
|
|
4
|
+
interface PeerIdOptions {
|
|
5
|
+
type: 'RSA' | 'Ed25519' | 'secp256k1';
|
|
6
|
+
multihash: MultihashDigest;
|
|
7
|
+
privateKey?: Uint8Array;
|
|
8
|
+
}
|
|
9
|
+
interface RSAPeerIdOptions {
|
|
10
|
+
multihash: MultihashDigest;
|
|
11
|
+
privateKey?: Uint8Array;
|
|
12
|
+
publicKey?: Uint8Array;
|
|
13
|
+
}
|
|
14
|
+
interface Ed25519PeerIdOptions {
|
|
15
|
+
multihash: MultihashDigest;
|
|
16
|
+
privateKey?: Uint8Array;
|
|
17
|
+
}
|
|
18
|
+
interface Secp256k1PeerIdOptions {
|
|
19
|
+
multihash: MultihashDigest;
|
|
20
|
+
privateKey?: Uint8Array;
|
|
21
|
+
}
|
|
22
|
+
export declare class PeerId {
|
|
23
|
+
type: 'RSA' | 'Ed25519' | 'secp256k1';
|
|
24
|
+
readonly multihash: MultihashDigest;
|
|
25
|
+
readonly privateKey?: Uint8Array;
|
|
26
|
+
readonly publicKey?: Uint8Array;
|
|
27
|
+
constructor(opts: PeerIdOptions);
|
|
28
|
+
toString(codec?: MultibaseEncoder<any>): string;
|
|
29
|
+
toCID(): CID;
|
|
30
|
+
toBytes(): Uint8Array;
|
|
31
|
+
/**
|
|
32
|
+
* Checks the equality of `this` peer against a given PeerId.
|
|
33
|
+
*
|
|
34
|
+
* @param {Uint8Array|PeerId} id
|
|
35
|
+
* @returns {boolean}
|
|
36
|
+
*/
|
|
37
|
+
equals(id: any): boolean;
|
|
38
|
+
static fromString(str: string, decoder?: MultibaseDecoder<any>): Ed25519PeerId | Secp256k1PeerId | RSAPeerId;
|
|
39
|
+
static fromBytes(buf: Uint8Array): Ed25519PeerId | Secp256k1PeerId | RSAPeerId;
|
|
40
|
+
static fromCID(cid: CID): Ed25519PeerId | Secp256k1PeerId | RSAPeerId;
|
|
41
|
+
/**
|
|
42
|
+
* @param publicKey - A marshalled public key
|
|
43
|
+
* @param privateKey - A marshalled private key
|
|
44
|
+
*/
|
|
45
|
+
static fromKeys(publicKey: Uint8Array, privateKey?: Uint8Array): Promise<Ed25519PeerId | Secp256k1PeerId | RSAPeerId>;
|
|
46
|
+
}
|
|
47
|
+
export declare class RSAPeerId extends PeerId {
|
|
48
|
+
readonly type = "RSA";
|
|
49
|
+
readonly publicKey?: Uint8Array;
|
|
50
|
+
constructor(opts: RSAPeerIdOptions);
|
|
51
|
+
}
|
|
52
|
+
export declare class Ed25519PeerId extends PeerId {
|
|
53
|
+
readonly type = "Ed25519";
|
|
54
|
+
readonly publicKey: Uint8Array;
|
|
55
|
+
constructor(opts: Ed25519PeerIdOptions);
|
|
56
|
+
}
|
|
57
|
+
export declare class Secp256k1PeerId extends PeerId {
|
|
58
|
+
readonly type = "secp256k1";
|
|
59
|
+
readonly publicKey: Uint8Array;
|
|
60
|
+
constructor(opts: Secp256k1PeerIdOptions);
|
|
61
|
+
}
|
|
62
|
+
export {};
|
|
63
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAA;AAMtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAA;AAC5F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAA;AAe1E,UAAU,aAAa;IACrB,IAAI,EAAE,KAAK,GAAG,SAAS,GAAG,WAAW,CAAA;IACrC,SAAS,EAAE,eAAe,CAAA;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAA;CACxB;AAED,UAAU,gBAAgB;IACxB,SAAS,EAAE,eAAe,CAAA;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,SAAS,CAAC,EAAE,UAAU,CAAA;CACvB;AAED,UAAU,oBAAoB;IAC5B,SAAS,EAAE,eAAe,CAAA;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAA;CACxB;AAED,UAAU,sBAAsB;IAC9B,SAAS,EAAE,eAAe,CAAA;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAA;CACxB;AAED,qBAAa,MAAM;IACV,IAAI,EAAE,KAAK,GAAG,SAAS,GAAG,WAAW,CAAA;IAC5C,SAAgB,SAAS,EAAE,eAAe,CAAA;IAC1C,SAAgB,UAAU,CAAC,EAAE,UAAU,CAAA;IACvC,SAAgB,SAAS,CAAC,EAAE,UAAU,CAAA;gBAEzB,IAAI,EAAE,aAAa;IAMhC,QAAQ,CAAE,KAAK,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC;IAUvC,KAAK;IAIL,OAAO;IAIP;;;;;OAKG;IACH,MAAM,CAAE,EAAE,EAAE,GAAG;IAUf,MAAM,CAAC,UAAU,CAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC;IAoB/D,MAAM,CAAC,SAAS,CAAE,GAAG,EAAE,UAAU;IAsBjC,MAAM,CAAC,OAAO,CAAE,GAAG,EAAE,GAAG;IAoBxB;;;OAGG;WACU,QAAQ,CAAE,SAAS,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,UAAU;CAWtE;AAED,qBAAa,SAAU,SAAQ,MAAM;IACnC,SAAgB,IAAI,SAAQ;IAC5B,SAAgB,SAAS,CAAC,EAAE,UAAU,CAAA;gBAEzB,IAAI,EAAE,gBAAgB;CAKpC;AAED,qBAAa,aAAc,SAAQ,MAAM;IACvC,SAAgB,IAAI,aAAY;IAChC,SAAgB,SAAS,EAAE,UAAU,CAAA;gBAExB,IAAI,EAAE,oBAAoB;CAKxC;AAED,qBAAa,eAAgB,SAAQ,MAAM;IACzC,SAAgB,IAAI,eAAc;IAClC,SAAgB,SAAS,EAAE,UAAU,CAAA;gBAExB,IAAI,EAAE,sBAAsB;CAK1C"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { CID } from 'multiformats/cid';
|
|
2
|
+
import { bases } from 'multiformats/basics';
|
|
3
|
+
import { base58btc } from 'multiformats/bases/base58';
|
|
4
|
+
import * as Digest from 'multiformats/hashes/digest';
|
|
5
|
+
import { identity } from 'multiformats/hashes/identity';
|
|
6
|
+
import { equals as uint8ArrayEquals } from 'uint8arrays/equals';
|
|
7
|
+
import { sha256 } from 'multiformats/hashes/sha2';
|
|
8
|
+
const baseDecoder = Object
|
|
9
|
+
.values(bases)
|
|
10
|
+
.map(codec => codec.decoder)
|
|
11
|
+
// @ts-expect-error https://github.com/multiformats/js-multiformats/issues/141
|
|
12
|
+
.reduce((acc, curr) => acc.or(curr), bases.identity.decoder);
|
|
13
|
+
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
|
14
|
+
const LIBP2P_KEY_CODE = 0x72;
|
|
15
|
+
const MARSHALLED_ED225519_PUBLIC_KEY_LENGTH = 36;
|
|
16
|
+
const MARSHALLED_SECP258K1_PUBLIC_KEY_LENGTH = 37;
|
|
17
|
+
export class PeerId {
|
|
18
|
+
constructor(opts) {
|
|
19
|
+
this.type = opts.type;
|
|
20
|
+
this.multihash = opts.multihash;
|
|
21
|
+
this.privateKey = opts.privateKey;
|
|
22
|
+
}
|
|
23
|
+
toString(codec) {
|
|
24
|
+
if (codec == null) {
|
|
25
|
+
codec = base58btc;
|
|
26
|
+
}
|
|
27
|
+
return codec.encode(this.multihash.bytes).slice(1);
|
|
28
|
+
}
|
|
29
|
+
// return self-describing String representation
|
|
30
|
+
// in default format from RFC 0001: https://github.com/libp2p/specs/pull/209
|
|
31
|
+
toCID() {
|
|
32
|
+
return CID.createV1(LIBP2P_KEY_CODE, this.multihash);
|
|
33
|
+
}
|
|
34
|
+
toBytes() {
|
|
35
|
+
return this.multihash.bytes;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Checks the equality of `this` peer against a given PeerId.
|
|
39
|
+
*
|
|
40
|
+
* @param {Uint8Array|PeerId} id
|
|
41
|
+
* @returns {boolean}
|
|
42
|
+
*/
|
|
43
|
+
equals(id) {
|
|
44
|
+
if (id instanceof Uint8Array) {
|
|
45
|
+
return uint8ArrayEquals(this.multihash.bytes, id);
|
|
46
|
+
}
|
|
47
|
+
else if (id?.multihash?.bytes != null) {
|
|
48
|
+
return uint8ArrayEquals(this.multihash.bytes, id.multihash.bytes);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
throw new Error('not valid Id');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
static fromString(str, decoder) {
|
|
55
|
+
decoder = decoder ?? baseDecoder;
|
|
56
|
+
if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
|
|
57
|
+
// identity hash ed25519/secp256k1 key or sha2-256 hash of
|
|
58
|
+
// rsa public key - base58btc encoded either way
|
|
59
|
+
const multihash = Digest.decode(base58btc.decode(`z${str}`));
|
|
60
|
+
if (str.startsWith('12D')) {
|
|
61
|
+
return new Ed25519PeerId({ multihash });
|
|
62
|
+
}
|
|
63
|
+
else if (str.startsWith('16U')) {
|
|
64
|
+
return new Secp256k1PeerId({ multihash });
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return new RSAPeerId({ multihash });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return PeerId.fromBytes(baseDecoder.decode(str));
|
|
71
|
+
}
|
|
72
|
+
static fromBytes(buf) {
|
|
73
|
+
try {
|
|
74
|
+
const multihash = Digest.decode(buf);
|
|
75
|
+
if (multihash.code === identity.code) {
|
|
76
|
+
if (multihash.digest.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
|
|
77
|
+
return new Ed25519PeerId({ multihash });
|
|
78
|
+
}
|
|
79
|
+
else if (multihash.digest.length === MARSHALLED_SECP258K1_PUBLIC_KEY_LENGTH) {
|
|
80
|
+
return new Secp256k1PeerId({ multihash });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (multihash.code === sha256.code) {
|
|
84
|
+
return new RSAPeerId({ multihash });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return PeerId.fromCID(CID.decode(buf));
|
|
89
|
+
}
|
|
90
|
+
throw new Error('Supplied PeerID CID is invalid');
|
|
91
|
+
}
|
|
92
|
+
static fromCID(cid) {
|
|
93
|
+
if (cid == null || cid.multihash == null || cid.version == null || (cid.version === 1 && cid.code !== LIBP2P_KEY_CODE)) {
|
|
94
|
+
throw new Error('Supplied PeerID CID is invalid');
|
|
95
|
+
}
|
|
96
|
+
const multihash = cid.multihash;
|
|
97
|
+
if (multihash.code === sha256.code) {
|
|
98
|
+
return new RSAPeerId({ multihash: cid.multihash });
|
|
99
|
+
}
|
|
100
|
+
else if (multihash.code === identity.code) {
|
|
101
|
+
if (multihash.bytes.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
|
|
102
|
+
return new Ed25519PeerId({ multihash: cid.multihash });
|
|
103
|
+
}
|
|
104
|
+
else if (multihash.bytes.length === MARSHALLED_SECP258K1_PUBLIC_KEY_LENGTH) {
|
|
105
|
+
return new Secp256k1PeerId({ multihash: cid.multihash });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
throw new Error('Supplied PeerID CID is invalid');
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* @param publicKey - A marshalled public key
|
|
112
|
+
* @param privateKey - A marshalled private key
|
|
113
|
+
*/
|
|
114
|
+
static async fromKeys(publicKey, privateKey) {
|
|
115
|
+
if (publicKey.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
|
|
116
|
+
return new Ed25519PeerId({ multihash: Digest.create(identity.code, publicKey), privateKey });
|
|
117
|
+
}
|
|
118
|
+
if (publicKey.length === MARSHALLED_SECP258K1_PUBLIC_KEY_LENGTH) {
|
|
119
|
+
return new Secp256k1PeerId({ multihash: Digest.create(identity.code, publicKey), privateKey });
|
|
120
|
+
}
|
|
121
|
+
return new RSAPeerId({ multihash: await sha256.digest(publicKey), publicKey, privateKey });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
export class RSAPeerId extends PeerId {
|
|
125
|
+
constructor(opts) {
|
|
126
|
+
super({ ...opts, type: 'RSA' });
|
|
127
|
+
this.type = 'RSA';
|
|
128
|
+
this.publicKey = opts.publicKey;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export class Ed25519PeerId extends PeerId {
|
|
132
|
+
constructor(opts) {
|
|
133
|
+
super({ ...opts, type: 'Ed25519' });
|
|
134
|
+
this.type = 'Ed25519';
|
|
135
|
+
this.publicKey = opts.multihash.digest;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
export class Secp256k1PeerId extends PeerId {
|
|
139
|
+
constructor(opts) {
|
|
140
|
+
super({ ...opts, type: 'secp256k1' });
|
|
141
|
+
this.type = 'secp256k1';
|
|
142
|
+
this.publicKey = opts.multihash.digest;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,57 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@libp2p/peer-id",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "IPFS Peer Id implementation in Node.js",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"types": "./dist/src/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/src/index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"src",
|
|
14
|
+
"dist/src",
|
|
15
|
+
"!**/*.tsbuildinfo"
|
|
16
|
+
],
|
|
17
|
+
"eslintConfig": {
|
|
18
|
+
"extends": "ipfs",
|
|
19
|
+
"parserOptions": {
|
|
20
|
+
"sourceType": "module"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"pretest": "npm run build",
|
|
25
|
+
"test": "aegir test -f ./dist/test/**/*.js",
|
|
26
|
+
"test:browser": "aegir test -t browser -f ./dist/test/**/*.js",
|
|
27
|
+
"test:node": "aegir test -t node -f ./dist/test/**/*.js",
|
|
28
|
+
"test:electron-main": "aegir test -t electron-main -f ./dist/test/**/*.js",
|
|
29
|
+
"lint": "aegir ts -p check && aegir lint",
|
|
30
|
+
"build": "tsc",
|
|
31
|
+
"dep-check": "aegir dep-check dist/src/**/*.js dist/test/**/*.js"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"IPFS"
|
|
35
|
+
],
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=15.0.0"
|
|
39
|
+
},
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "git+https://github.com/libp2p/js-libp2p-interfaces.git"
|
|
43
|
+
},
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/libp2p/js-libp2p-interfaces/issues"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://github.com/libp2p/js-libp2p-interfaces/tree/master/packages/libp2p-peer-id#readme",
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"aegir": "^36.0.1"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@libp2p/interfaces": "^0.2.0",
|
|
53
|
+
"multiformats": "^9.4.5",
|
|
54
|
+
"uint8arrays": "^3.0.0"
|
|
55
|
+
},
|
|
56
|
+
"gitHead": "899cb6a9390c748bccf9b6404f104efb011a0c9c"
|
|
7
57
|
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { CID } from 'multiformats/cid'
|
|
2
|
+
import { bases } from 'multiformats/basics'
|
|
3
|
+
import { base58btc } from 'multiformats/bases/base58'
|
|
4
|
+
import * as Digest from 'multiformats/hashes/digest'
|
|
5
|
+
import { identity } from 'multiformats/hashes/identity'
|
|
6
|
+
import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
|
|
7
|
+
import type { MultibaseDecoder, MultibaseEncoder } from 'multiformats/types/bases/interface'
|
|
8
|
+
import type { MultihashDigest } from 'multiformats/types/hashes/interface'
|
|
9
|
+
import { sha256 } from 'multiformats/hashes/sha2'
|
|
10
|
+
|
|
11
|
+
const baseDecoder = Object
|
|
12
|
+
.values(bases)
|
|
13
|
+
.map(codec => codec.decoder)
|
|
14
|
+
// @ts-expect-error https://github.com/multiformats/js-multiformats/issues/141
|
|
15
|
+
.reduce((acc, curr) => acc.or(curr), bases.identity.decoder)
|
|
16
|
+
|
|
17
|
+
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
|
18
|
+
const LIBP2P_KEY_CODE = 0x72
|
|
19
|
+
|
|
20
|
+
const MARSHALLED_ED225519_PUBLIC_KEY_LENGTH = 36
|
|
21
|
+
const MARSHALLED_SECP258K1_PUBLIC_KEY_LENGTH = 37
|
|
22
|
+
|
|
23
|
+
interface PeerIdOptions {
|
|
24
|
+
type: 'RSA' | 'Ed25519' | 'secp256k1'
|
|
25
|
+
multihash: MultihashDigest
|
|
26
|
+
privateKey?: Uint8Array
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface RSAPeerIdOptions {
|
|
30
|
+
multihash: MultihashDigest
|
|
31
|
+
privateKey?: Uint8Array
|
|
32
|
+
publicKey?: Uint8Array
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface Ed25519PeerIdOptions {
|
|
36
|
+
multihash: MultihashDigest
|
|
37
|
+
privateKey?: Uint8Array
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface Secp256k1PeerIdOptions {
|
|
41
|
+
multihash: MultihashDigest
|
|
42
|
+
privateKey?: Uint8Array
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export class PeerId {
|
|
46
|
+
public type: 'RSA' | 'Ed25519' | 'secp256k1'
|
|
47
|
+
public readonly multihash: MultihashDigest
|
|
48
|
+
public readonly privateKey?: Uint8Array
|
|
49
|
+
public readonly publicKey?: Uint8Array
|
|
50
|
+
|
|
51
|
+
constructor (opts: PeerIdOptions) {
|
|
52
|
+
this.type = opts.type
|
|
53
|
+
this.multihash = opts.multihash
|
|
54
|
+
this.privateKey = opts.privateKey
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
toString (codec?: MultibaseEncoder<any>) {
|
|
58
|
+
if (codec == null) {
|
|
59
|
+
codec = base58btc
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return codec.encode(this.multihash.bytes).slice(1)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// return self-describing String representation
|
|
66
|
+
// in default format from RFC 0001: https://github.com/libp2p/specs/pull/209
|
|
67
|
+
toCID () {
|
|
68
|
+
return CID.createV1(LIBP2P_KEY_CODE, this.multihash)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
toBytes () {
|
|
72
|
+
return this.multihash.bytes
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Checks the equality of `this` peer against a given PeerId.
|
|
77
|
+
*
|
|
78
|
+
* @param {Uint8Array|PeerId} id
|
|
79
|
+
* @returns {boolean}
|
|
80
|
+
*/
|
|
81
|
+
equals (id: any) {
|
|
82
|
+
if (id instanceof Uint8Array) {
|
|
83
|
+
return uint8ArrayEquals(this.multihash.bytes, id)
|
|
84
|
+
} else if (id?.multihash?.bytes != null) {
|
|
85
|
+
return uint8ArrayEquals(this.multihash.bytes, id.multihash.bytes)
|
|
86
|
+
} else {
|
|
87
|
+
throw new Error('not valid Id')
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static fromString (str: string, decoder?: MultibaseDecoder<any>) {
|
|
92
|
+
decoder = decoder ?? baseDecoder
|
|
93
|
+
|
|
94
|
+
if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
|
|
95
|
+
// identity hash ed25519/secp256k1 key or sha2-256 hash of
|
|
96
|
+
// rsa public key - base58btc encoded either way
|
|
97
|
+
const multihash = Digest.decode(base58btc.decode(`z${str}`))
|
|
98
|
+
|
|
99
|
+
if (str.startsWith('12D')) {
|
|
100
|
+
return new Ed25519PeerId({ multihash })
|
|
101
|
+
} else if (str.startsWith('16U')) {
|
|
102
|
+
return new Secp256k1PeerId({ multihash })
|
|
103
|
+
} else {
|
|
104
|
+
return new RSAPeerId({ multihash })
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return PeerId.fromBytes(baseDecoder.decode(str))
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
static fromBytes (buf: Uint8Array) {
|
|
112
|
+
try {
|
|
113
|
+
const multihash = Digest.decode(buf)
|
|
114
|
+
|
|
115
|
+
if (multihash.code === identity.code) {
|
|
116
|
+
if (multihash.digest.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
|
|
117
|
+
return new Ed25519PeerId({ multihash })
|
|
118
|
+
} else if (multihash.digest.length === MARSHALLED_SECP258K1_PUBLIC_KEY_LENGTH) {
|
|
119
|
+
return new Secp256k1PeerId({ multihash })
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (multihash.code === sha256.code) {
|
|
124
|
+
return new RSAPeerId({ multihash })
|
|
125
|
+
}
|
|
126
|
+
} catch {
|
|
127
|
+
return PeerId.fromCID(CID.decode(buf))
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
throw new Error('Supplied PeerID CID is invalid')
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
static fromCID (cid: CID) {
|
|
134
|
+
if (cid == null || cid.multihash == null || cid.version == null || (cid.version === 1 && cid.code !== LIBP2P_KEY_CODE)) {
|
|
135
|
+
throw new Error('Supplied PeerID CID is invalid')
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const multihash = cid.multihash
|
|
139
|
+
|
|
140
|
+
if (multihash.code === sha256.code) {
|
|
141
|
+
return new RSAPeerId({ multihash: cid.multihash })
|
|
142
|
+
} else if (multihash.code === identity.code) {
|
|
143
|
+
if (multihash.bytes.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
|
|
144
|
+
return new Ed25519PeerId({ multihash: cid.multihash })
|
|
145
|
+
} else if (multihash.bytes.length === MARSHALLED_SECP258K1_PUBLIC_KEY_LENGTH) {
|
|
146
|
+
return new Secp256k1PeerId({ multihash: cid.multihash })
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
throw new Error('Supplied PeerID CID is invalid')
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @param publicKey - A marshalled public key
|
|
155
|
+
* @param privateKey - A marshalled private key
|
|
156
|
+
*/
|
|
157
|
+
static async fromKeys (publicKey: Uint8Array, privateKey?: Uint8Array) {
|
|
158
|
+
if (publicKey.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
|
|
159
|
+
return new Ed25519PeerId({ multihash: Digest.create(identity.code, publicKey), privateKey })
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (publicKey.length === MARSHALLED_SECP258K1_PUBLIC_KEY_LENGTH) {
|
|
163
|
+
return new Secp256k1PeerId({ multihash: Digest.create(identity.code, publicKey), privateKey })
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return new RSAPeerId({ multihash: await sha256.digest(publicKey), publicKey, privateKey })
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export class RSAPeerId extends PeerId {
|
|
171
|
+
public readonly type = 'RSA'
|
|
172
|
+
public readonly publicKey?: Uint8Array
|
|
173
|
+
|
|
174
|
+
constructor (opts: RSAPeerIdOptions) {
|
|
175
|
+
super({ ...opts, type: 'RSA' })
|
|
176
|
+
|
|
177
|
+
this.publicKey = opts.publicKey
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export class Ed25519PeerId extends PeerId {
|
|
182
|
+
public readonly type = 'Ed25519'
|
|
183
|
+
public readonly publicKey: Uint8Array
|
|
184
|
+
|
|
185
|
+
constructor (opts: Ed25519PeerIdOptions) {
|
|
186
|
+
super({ ...opts, type: 'Ed25519' })
|
|
187
|
+
|
|
188
|
+
this.publicKey = opts.multihash.digest
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export class Secp256k1PeerId extends PeerId {
|
|
193
|
+
public readonly type = 'secp256k1'
|
|
194
|
+
public readonly publicKey: Uint8Array
|
|
195
|
+
|
|
196
|
+
constructor (opts: Secp256k1PeerIdOptions) {
|
|
197
|
+
super({ ...opts, type: 'secp256k1' })
|
|
198
|
+
|
|
199
|
+
this.publicKey = opts.multihash.digest
|
|
200
|
+
}
|
|
201
|
+
}
|