Skip to content

Commit

Permalink
feat: support Peer ID represented 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 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 <lidel@lidel.org>
  • Loading branch information
lidel committed Oct 25, 2019
1 parent 4d5bb2c commit 60072e1
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 7 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@
- [Import](#import)
- [`createFromHexString(str)`](#createfromhexstringstr)
- [`createFromBytes(buf)`](#createfrombytesbuf)
- [`createFromCID(cid)`](#createfromcidcid)
- [`createFromB58String(str)`](#createfromb58stringstr)
- [`createFromPubKey(pubKey)`](#createfrompubkeypubkey)
- [`createFromPrivKey(privKey)`](#createfromprivkeyprivkey)
- [`createFromJSON(obj)`](#createfromjsonobj)
- [Export](#export)
- [`toHexString()`](#tohexstring)
- [`toBytes()`](#tobytes)
- [`toCIDString()`](#tob58string)
- [`toB58String()`](#tob58string)
- [`toJSON()`](#tojson)
- [`toPrint()`](#toprint)
Expand Down Expand Up @@ -145,6 +147,14 @@ Creates a Peer ID from a buffer representing the key's multihash.

Returns `PeerId`.

### `createFromCID(cid)`

- `cid: CID|String|Buffer` - The multihash encoded as [CID](https://github.com/ipld/js-cid) (object, `String` or `Buffer`)

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)).

Returns `PeerId`.

### `createFromB58String(str)`

Creates a Peer ID from a Base58 string representing the key's multihash.
Expand Down Expand Up @@ -197,6 +207,15 @@ Returns the Peer ID's `id` as a buffer.
<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>
```


### `toCIDString()`

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))

```
bafzbeigweq4zr4x4ky2dvv7nanbkw6egutvrrvzw6g3h2rftp7gidyhtt4
```

### `toB58String()`

Returns the Peer ID's `id` as a base58 string.
Expand Down
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 60072e1

Please sign in to comment.