@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 ADDED
@@ -0,0 +1,4 @@
1
+ This project is dual licensed under MIT and Apache-2.0.
2
+
3
+ MIT: https://www.opensource.org/licenses/mit
4
+ Apache-2.0: https://www.apache.org/licenses/license-2.0
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.0.0",
4
- "description": "",
5
- "main": "index.js",
6
- "license": "(Apache-2.0 OR MIT)"
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
+ }