Skip to content

Commit

Permalink
feat: add support for text representation as CID
Browse files Browse the repository at this point in the history
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 <lidel@lidel.org>
  • Loading branch information
lidel committed Oct 24, 2019
1 parent 4d5bb2c commit f056623
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 7 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"dirty-chai": "^2.0.1"
},
"dependencies": {
"cids": "~0.7.1",
"class-is": "^1.1.0",
"libp2p-crypto": "~0.17.0",
"multihashes": "~0.4.15",
Expand Down
19 changes: 19 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
'use strict'

const mh = require('multihashes')
const CID = require('cids')
const cryptoKeys = require('libp2p-crypto/src/keys')
const assert = require('assert')
const withIs = require('class-is')
Expand Down Expand Up @@ -122,6 +123,12 @@ class PeerId {
return this._idB58String
}

// return string representation from RFC 0001: https://github.com/libp2p/specs/pull/209
toCIDString () {
const cid = new CID(1, 'libp2p-key', this.id, 'base32')
return cid.toBaseEncodedString('base32')
}

isEqual (id) {
if (Buffer.isBuffer(id)) {
return this.id.equals(id)
Expand Down Expand Up @@ -187,6 +194,18 @@ exports.createFromB58String = (str) => {
return new PeerIdWithIs(mh.fromB58String(str))
}

exports.createFromCID = (cid) => {
if (typeof cid === 'string' || Buffer.isBuffer(cid)) {
cid = new CID(cid)
} else if (CID.isCID(cid)) {
CID.validateCID(cid) // throws on error
} else {
// provide more meaningful error than the one in CID.validateCID
throw new Error('Supplied cid value is neither String|CID|Buffer')
}
return new PeerIdWithIs(cid.multihash)
}

// Public Key input will be a buffer
exports.createFromPubKey = async (key) => {
let buf = key
Expand Down
58 changes: 51 additions & 7 deletions test/peer-id.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ chai.use(dirtyChai)
const expect = chai.expect
const crypto = require('libp2p-crypto')
const mh = require('multihashes')
const CID = require('cids')

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

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

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

Expand Down Expand Up @@ -63,27 +66,68 @@ describe('PeerId', () => {
}).to.throw(/immutable/)
})

it('recreate an Id from Hex string', () => {
it('recreate from Hex string', () => {
const id = PeerId.createFromHexString(testIdHex)
expect(testIdBytes).to.deep.equal(id.id)
expect(testIdBytes).to.deep.equal(id.toBytes())
})

it('Recreate an Id from a Buffer', () => {
it('recreate from a Buffer', () => {
const id = PeerId.createFromBytes(testIdBytes)
expect(testId.id).to.equal(id.toHexString())
expect(testIdBytes).to.deep.equal(id.toBytes())
})

it('Recreate a B58 String', () => {
it('recreate from a B58 String', () => {
const id = PeerId.createFromB58String(testIdB58String)
expect(testIdB58String).to.equal(id.toB58String())
expect(testIdBytes).to.deep.equal(id.toBytes())
})

it('Recreate from a Public Key', async () => {
it('recreate from CID object', () => {
const id = PeerId.createFromCID(testIdCID)
expect(testIdCIDString).to.equal(id.toCIDString())
expect(testIdBytes).to.deep.equal(id.toBytes())
})

it('recreate from Base58 String (CIDv0))', () => {
const id = PeerId.createFromCID(testIdB58String)
expect(testIdCIDString).to.equal(id.toCIDString())
expect(testIdBytes).to.deep.equal(id.toBytes())
})

it('recreate from CIDv1 Base32', () => {
const id = PeerId.createFromCID(testIdCIDString)
expect(testIdCIDString).to.equal(id.toCIDString())
expect(testId.id).to.equal(id.toHexString())
})

it('recreate from CID Buffer', () => {
const id = PeerId.createFromCID(testIdCID.buffer)
expect(testIdCIDString).to.equal(id.toCIDString())
expect(testIdBytes).to.deep.equal(id.toBytes())
})

it('throws on invalid CID value', async () => {
const invalidCID = 'QmaozNR7DZHQK1ZcU9p7QdrshMvXqWK6gpu5rmrkPdT3L'
expect(() => {
PeerId.createFromCID(invalidCID)
}).to.throw(/multihash unknown function code: 0x50/)
})

it('throws on invalid CID object', async () => {
const invalidCID = {}
expect(() => {
PeerId.createFromCID(invalidCID)
}).to.throw(/Supplied cid value is neither String|CID|Buffer/)
})

it('recreate from a Public Key', async () => {
const id = await PeerId.createFromPubKey(testId.pubKey)
expect(testIdB58String).to.equal(id.toB58String())
expect(testIdBytes).to.deep.equal(id.toBytes())
})

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

it('Recreate from Protobuf', async () => {
it('recreate from Protobuf', async () => {
const id = await PeerId.createFromProtobuf(testId.marshaled)
expect(testIdB58String).to.equal(id.toB58String())
const encoded = Buffer.from(testId.privKey, 'base64')
Expand Down

0 comments on commit f056623

Please sign in to comment.