Skip to content

Commit f056623

Browse files
committed
feat: add support for text representation as CID
This change adds two functions: - createFromCID accepts CID as String|CID|Buffer and created 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 f056623

File tree

3 files changed

+71
-7
lines changed

3 files changed

+71
-7
lines changed

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', async () => {
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', async () => {
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)