Skip to content

Commit d7d78de

Browse files
committed
feat: support Peer ID represented as CID
This change adds two functions: - createFromCID accepts CID as String|CID|Buffer and creates PeerId from the multihash value inside of it - toCIDString serializes PeerId multihash into a CIDv1 in Base32, as agreed in libp2p/specs#209 License: MIT Signed-off-by: Marcin Rataj <[email protected]>
1 parent 4d5bb2c commit d7d78de

File tree

4 files changed

+90
-7
lines changed

4 files changed

+90
-7
lines changed

README.md

+19
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,15 @@
3232
- [Import](#import)
3333
- [`createFromHexString(str)`](#createfromhexstringstr)
3434
- [`createFromBytes(buf)`](#createfrombytesbuf)
35+
- [`createFromCID(cid)`](#createfromcidcid)
3536
- [`createFromB58String(str)`](#createfromb58stringstr)
3637
- [`createFromPubKey(pubKey)`](#createfrompubkeypubkey)
3738
- [`createFromPrivKey(privKey)`](#createfromprivkeyprivkey)
3839
- [`createFromJSON(obj)`](#createfromjsonobj)
3940
- [Export](#export)
4041
- [`toHexString()`](#tohexstring)
4142
- [`toBytes()`](#tobytes)
43+
- [`toCIDString()`](#tob58string)
4244
- [`toB58String()`](#tob58string)
4345
- [`toJSON()`](#tojson)
4446
- [`toPrint()`](#toprint)
@@ -145,6 +147,14 @@ Creates a Peer ID from a buffer representing the key's multihash.
145147

146148
Returns `PeerId`.
147149

150+
### `createFromCID(cid)`
151+
152+
- `cid: CID|String|Buffer` - The multihash encoded as [CID](https://github.com/ipld/js-cid) (object, `String` or `Buffer`)
153+
154+
Creates a Peer ID from a CID representation of the key's multihash ([RFC 0001](https://github.com/libp2p/specs/blob/master/RFC/0001-text-peerid-cid.md)).
155+
156+
Returns `PeerId`.
157+
148158
### `createFromB58String(str)`
149159

150160
Creates a Peer ID from a Base58 string representing the key's multihash.
@@ -197,6 +207,15 @@ Returns the Peer ID's `id` as a buffer.
197207
<Buffer 12 20 d6 24 39 98 f2 fc 56 34 3a d7 ed 03 42 ab 78 86 a4 eb 18 d7 36 f1 b6 7d 44 b3 7f cc 81 e0 f3 9f>
198208
```
199209

210+
211+
### `toCIDString()`
212+
213+
Returns the Peer ID's `id` as a self-describing CIDv1 in Base32 ([RFC 0001](https://github.com/libp2p/specs/blob/master/RFC/0001-text-peerid-cid.md))
214+
215+
```
216+
bafzbeigweq4zr4x4ky2dvv7nanbkw6egutvrrvzw6g3h2rftp7gidyhtt4
217+
```
218+
200219
### `toB58String()`
201220

202221
Returns the Peer ID's `id` as a base58 string.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"dirty-chai": "^2.0.1"
4141
},
4242
"dependencies": {
43+
"cids": "~0.7.1",
4344
"class-is": "^1.1.0",
4445
"libp2p-crypto": "~0.17.0",
4546
"multihashes": "~0.4.15",

src/index.js

+19
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
'use strict'
66

77
const mh = require('multihashes')
8+
const CID = require('cids')
89
const cryptoKeys = require('libp2p-crypto/src/keys')
910
const assert = require('assert')
1011
const withIs = require('class-is')
@@ -122,6 +123,12 @@ class PeerId {
122123
return this._idB58String
123124
}
124125

126+
// return string representation from RFC 0001: https://github.com/libp2p/specs/pull/209
127+
toCIDString () {
128+
const cid = new CID(1, 'libp2p-key', this.id, 'base32')
129+
return cid.toBaseEncodedString('base32')
130+
}
131+
125132
isEqual (id) {
126133
if (Buffer.isBuffer(id)) {
127134
return this.id.equals(id)
@@ -187,6 +194,18 @@ exports.createFromB58String = (str) => {
187194
return new PeerIdWithIs(mh.fromB58String(str))
188195
}
189196

197+
exports.createFromCID = (cid) => {
198+
if (typeof cid === 'string' || Buffer.isBuffer(cid)) {
199+
cid = new CID(cid)
200+
} else if (CID.isCID(cid)) {
201+
CID.validateCID(cid) // throws on error
202+
} else {
203+
// provide more meaningful error than the one in CID.validateCID
204+
throw new Error('Supplied cid value is neither String|CID|Buffer')
205+
}
206+
return new PeerIdWithIs(cid.multihash)
207+
}
208+
190209
// Public Key input will be a buffer
191210
exports.createFromPubKey = async (key) => {
192211
let buf = key

test/peer-id.spec.js

+51-7
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ chai.use(dirtyChai)
88
const expect = chai.expect
99
const crypto = require('libp2p-crypto')
1010
const mh = require('multihashes')
11+
const CID = require('cids')
1112

1213
const PeerId = require('../src')
1314

@@ -17,6 +18,8 @@ const testId = require('./fixtures/sample-id')
1718
const testIdHex = testId.id
1819
const testIdBytes = mh.fromHexString(testId.id)
1920
const testIdB58String = mh.toB58String(testIdBytes)
21+
const testIdCID = new CID(1, 'libp2p-key', testIdBytes)
22+
const testIdCIDString = testIdCID.toBaseEncodedString('base32')
2023

2124
const goId = require('./fixtures/go-private-key')
2225

@@ -63,27 +66,68 @@ describe('PeerId', () => {
6366
}).to.throw(/immutable/)
6467
})
6568

66-
it('recreate an Id from Hex string', () => {
69+
it('recreate from Hex string', () => {
6770
const id = PeerId.createFromHexString(testIdHex)
68-
expect(testIdBytes).to.deep.equal(id.id)
71+
expect(testIdBytes).to.deep.equal(id.toBytes())
6972
})
7073

71-
it('Recreate an Id from a Buffer', () => {
74+
it('recreate from a Buffer', () => {
7275
const id = PeerId.createFromBytes(testIdBytes)
7376
expect(testId.id).to.equal(id.toHexString())
77+
expect(testIdBytes).to.deep.equal(id.toBytes())
7478
})
7579

76-
it('Recreate a B58 String', () => {
80+
it('recreate from a B58 String', () => {
7781
const id = PeerId.createFromB58String(testIdB58String)
7882
expect(testIdB58String).to.equal(id.toB58String())
83+
expect(testIdBytes).to.deep.equal(id.toBytes())
7984
})
8085

81-
it('Recreate from a Public Key', async () => {
86+
it('recreate from CID object', () => {
87+
const id = PeerId.createFromCID(testIdCID)
88+
expect(testIdCIDString).to.equal(id.toCIDString())
89+
expect(testIdBytes).to.deep.equal(id.toBytes())
90+
})
91+
92+
it('recreate from Base58 String (CIDv0))', () => {
93+
const id = PeerId.createFromCID(testIdB58String)
94+
expect(testIdCIDString).to.equal(id.toCIDString())
95+
expect(testIdBytes).to.deep.equal(id.toBytes())
96+
})
97+
98+
it('recreate from CIDv1 Base32', () => {
99+
const id = PeerId.createFromCID(testIdCIDString)
100+
expect(testIdCIDString).to.equal(id.toCIDString())
101+
expect(testId.id).to.equal(id.toHexString())
102+
})
103+
104+
it('recreate from CID Buffer', () => {
105+
const id = PeerId.createFromCID(testIdCID.buffer)
106+
expect(testIdCIDString).to.equal(id.toCIDString())
107+
expect(testIdBytes).to.deep.equal(id.toBytes())
108+
})
109+
110+
it('throws on invalid CID value', () => {
111+
const invalidCID = 'QmaozNR7DZHQK1ZcU9p7QdrshMvXqWK6gpu5rmrkPdT3L'
112+
expect(() => {
113+
PeerId.createFromCID(invalidCID)
114+
}).to.throw(/multihash unknown function code: 0x50/)
115+
})
116+
117+
it('throws on invalid CID object', () => {
118+
const invalidCID = {}
119+
expect(() => {
120+
PeerId.createFromCID(invalidCID)
121+
}).to.throw(/Supplied cid value is neither String|CID|Buffer/)
122+
})
123+
124+
it('recreate from a Public Key', async () => {
82125
const id = await PeerId.createFromPubKey(testId.pubKey)
83126
expect(testIdB58String).to.equal(id.toB58String())
127+
expect(testIdBytes).to.deep.equal(id.toBytes())
84128
})
85129

86-
it('Recreate from a Private Key', async () => {
130+
it('recreate from a Private Key', async () => {
87131
const id = await PeerId.createFromPrivKey(testId.privKey)
88132
expect(testIdB58String).to.equal(id.toB58String())
89133
const encoded = Buffer.from(testId.privKey, 'base64')
@@ -92,7 +136,7 @@ describe('PeerId', () => {
92136
expect(id.marshalPubKey()).to.deep.equal(id2.marshalPubKey())
93137
})
94138

95-
it('Recreate from Protobuf', async () => {
139+
it('recreate from Protobuf', async () => {
96140
const id = await PeerId.createFromProtobuf(testId.marshaled)
97141
expect(testIdB58String).to.equal(id.toB58String())
98142
const encoded = Buffer.from(testId.privKey, 'base64')

0 commit comments

Comments
 (0)