Skip to content

Commit 69d7a01

Browse files
chore: update to new multiformats (#149)
Replaces multihashes with the new multiformats module BREAKING CHANGE: uses the CID class from the new multiformats module Co-authored-by: Vasco Santos <[email protected]>
1 parent 173b3b3 commit 69d7a01

File tree

5 files changed

+125
-53
lines changed

5 files changed

+125
-53
lines changed

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
- [`createFromPrivKey(privKey)`](#createfromprivkeyprivkey)
4343
- [`createFromJSON(obj)`](#createfromjsonobj)
4444
- [`createFromProtobuf(buf)`](#createfromprotobufbuf)
45+
- [`parse(str)`](#parsestr)
4546
- [Export](#export)
4647
- [`toHexString()`](#tohexstring)
4748
- [`toBytes()`](#tobytes)
@@ -169,7 +170,7 @@ Returns `PeerId`.
169170

170171
### `createFromCID(cid)`
171172

172-
- `cid: CID|String|Buffer` - The multihash encoded as [CID](https://github.com/ipld/js-cid) (object, `String` or `Buffer`)
173+
- `cid: CID` - The multihash encoded as [CID](https://github.com/multiformats/js-multiformats/blob/master/src/cid.js) object
173174

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

@@ -209,6 +210,10 @@ Returns `Promise<PeerId>`.
209210

210211
`buf` is a protocol-buffers encoded PeerId (see `marshal()`)
211212

213+
### `parse(str)`
214+
215+
Attempts to create a PeerId from a base58btc encoded string or a CID encoded as a string.
216+
212217
## Export
213218

214219
### `toHexString()`

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"bin": "src/bin.js",
99
"scripts": {
1010
"lint": "aegir lint",
11+
"prepare": "npm run build",
1112
"build": "npm run build:proto && npm run build:proto-types && aegir build --no-types",
1213
"build:proto": "pbjs -t static-module -w commonjs -r libp2p-peer-id --force-number --no-verify --no-delimited --no-create --no-beautify --no-defaults --lint eslint-disable -o src/proto.js ./src/proto.proto",
1314
"build:proto-types": "pbts -o src/proto.d.ts src/proto.js",
@@ -41,14 +42,14 @@
4142
"@types/dirty-chai": "^2.0.2",
4243
"@types/mocha": "^8.2.0",
4344
"aegir": "^33.0.0",
45+
"multihashes": "^4.0.2",
4446
"util": "^0.12.3"
4547
},
4648
"dependencies": {
47-
"cids": "^1.1.5",
4849
"class-is": "^1.1.0",
4950
"libp2p-crypto": "^0.19.0",
5051
"minimist": "^1.2.5",
51-
"multihashes": "^4.0.2",
52+
"multiformats": "^9.0.0",
5253
"protobufjs": "^6.10.2",
5354
"uint8arrays": "^2.0.5"
5455
},

src/index.d.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { PrivateKey, PublicKey, KeyType } from "libp2p-crypto";
2-
import CID from 'cids'
2+
import { CID } from 'multiformats/cid'
33

44
declare namespace PeerId {
55
/**
@@ -68,7 +68,7 @@ declare namespace PeerId {
6868
* Create PeerId from CID.
6969
* @param cid The CID.
7070
*/
71-
function createFromCID(cid: CID | Uint8Array | string | object): PeerId;
71+
function createFromCID(cid: CID): PeerId;
7272

7373
/**
7474
* Create PeerId from public key.
@@ -94,6 +94,12 @@ declare namespace PeerId {
9494
* @param buf Protobuf bytes, as Uint8Array or hex-encoded string.
9595
*/
9696
function createFromProtobuf(buf: Uint8Array | string): Promise<PeerId>;
97+
98+
/**
99+
* Parse a PeerId from a string.
100+
* @param str encoded public key string.
101+
*/
102+
function parse(str: string): PeerId;
97103
}
98104

99105
/**

src/index.js

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,21 @@
44

55
'use strict'
66

7-
const mh = require('multihashes')
8-
const CID = require('cids')
7+
const { CID } = require('multiformats/cid')
8+
const { base58btc } = require('multiformats/bases/base58')
9+
const { base16 } = require('multiformats/bases/base16')
10+
const Digest = require('multiformats/hashes/digest')
911
const cryptoKeys = require('libp2p-crypto/src/keys')
1012
const withIs = require('class-is')
1113
const { PeerIdProto } = require('./proto')
1214
const uint8ArrayEquals = require('uint8arrays/equals')
1315
const uint8ArrayFromString = require('uint8arrays/from-string')
1416
const uint8ArrayToString = require('uint8arrays/to-string')
17+
const { identity } = require('multiformats/hashes/identity')
18+
19+
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
20+
const DAG_PB_CODE = 0x70
21+
const LIBP2P_KEY_CODE = 0x72
1522

1623
class PeerId {
1724
constructor (id, privKey, pubKey) {
@@ -24,7 +31,7 @@ class PeerId {
2431
}
2532

2633
this._id = id
27-
this._idB58String = mh.toB58String(this.id)
34+
this._idB58String = base58btc.encode(this.id).substring(1)
2835
this._privKey = privKey
2936
this._pubKey = pubKey
3037
}
@@ -55,9 +62,9 @@ class PeerId {
5562
}
5663

5764
try {
58-
const decoded = mh.decode(this.id)
65+
const decoded = Digest.decode(this.id)
5966

60-
if (decoded.name === 'identity') {
67+
if (decoded.code === identity.code) {
6168
this._pubKey = cryptoKeys.unmarshalPublicKey(decoded.digest)
6269
}
6370
} catch (_) {
@@ -121,7 +128,7 @@ class PeerId {
121128

122129
// encode/decode functions
123130
toHexString () {
124-
return mh.toHexString(this.id)
131+
return base16.encode(this.id).substring(1)
125132
}
126133

127134
toBytes () {
@@ -136,10 +143,10 @@ class PeerId {
136143
// in default format from RFC 0001: https://github.com/libp2p/specs/pull/209
137144
toString () {
138145
if (!this._idCIDString) {
139-
const cid = new CID(1, 'libp2p-key', this.id, 'base32')
146+
const cid = CID.createV1(LIBP2P_KEY_CODE, Digest.decode(this.id))
140147

141148
Object.defineProperty(this, '_idCIDString', {
142-
value: cid.toBaseEncodedString('base32'),
149+
value: cid.toString(),
143150
enumerable: false
144151
})
145152
}
@@ -192,8 +199,9 @@ class PeerId {
192199
*/
193200
hasInlinePublicKey () {
194201
try {
195-
const decoded = mh.decode(this.id)
196-
if (decoded.name === 'identity') {
202+
const decoded = Digest.decode(this.id)
203+
204+
if (decoded.code === identity.code) {
197205
return true
198206
}
199207
} catch (_) {
@@ -213,7 +221,7 @@ exports = module.exports = PeerIdWithIs
213221

214222
const computeDigest = (pubKey) => {
215223
if (pubKey.bytes.length <= 42) {
216-
return mh.encode(pubKey.bytes, 'identity')
224+
return Digest.create(identity.code, pubKey.bytes).bytes
217225
} else {
218226
return pubKey.hash()
219227
}
@@ -235,26 +243,46 @@ exports.create = async (opts) => {
235243
}
236244

237245
exports.createFromHexString = (str) => {
238-
return new PeerIdWithIs(mh.fromHexString(str))
246+
return new PeerIdWithIs(base16.decode('f' + str))
239247
}
240248

241249
exports.createFromBytes = (buf) => {
242-
return new PeerIdWithIs(buf)
250+
try {
251+
const cid = CID.decode(buf)
252+
253+
if (!validMulticodec(cid)) {
254+
throw new Error('Supplied PeerID CID is invalid')
255+
}
256+
257+
return exports.createFromCID(cid)
258+
} catch {
259+
const digest = Digest.decode(buf)
260+
261+
if (digest.code !== identity.code) {
262+
throw new Error('Supplied PeerID CID is invalid')
263+
}
264+
265+
return new PeerIdWithIs(buf)
266+
}
243267
}
244268

245269
exports.createFromB58String = (str) => {
246-
return exports.createFromCID(str) // B58String is CIDv0
270+
return exports.createFromBytes(base58btc.decode('z' + str))
247271
}
248272

249273
const validMulticodec = (cid) => {
250274
// supported: 'libp2p-key' (CIDv1) and 'dag-pb' (CIDv0 converted to CIDv1)
251-
return cid.codec === 'libp2p-key' || cid.codec === 'dag-pb'
275+
return cid.code === LIBP2P_KEY_CODE || cid.code === DAG_PB_CODE
252276
}
253277

254278
exports.createFromCID = (cid) => {
255-
cid = CID.isCID(cid) ? cid : new CID(cid)
256-
if (!validMulticodec(cid)) throw new Error('Supplied PeerID CID has invalid multicodec: ' + cid.codec)
257-
return new PeerIdWithIs(cid.multihash)
279+
cid = CID.asCID(cid)
280+
281+
if (!cid || !validMulticodec(cid)) {
282+
throw new Error('Supplied PeerID CID is invalid')
283+
}
284+
285+
return new PeerIdWithIs(cid.multihash.bytes)
258286
}
259287

260288
// Public Key input will be a Uint8Array
@@ -288,7 +316,7 @@ exports.createFromPrivKey = async (key) => {
288316
}
289317

290318
exports.createFromJSON = async (obj) => {
291-
const id = mh.fromB58String(obj.id)
319+
const id = base58btc.decode('z' + obj.id)
292320
const rawPrivKey = obj.privKey && uint8ArrayFromString(obj.privKey, 'base64pad')
293321
const rawPubKey = obj.pubKey && uint8ArrayFromString(obj.pubKey, 'base64pad')
294322
const pub = rawPubKey && await cryptoKeys.unmarshalPublicKey(rawPubKey)
@@ -360,6 +388,16 @@ exports.createFromProtobuf = async (buf) => {
360388
throw new Error('Protobuf did not contain any usable key material')
361389
}
362390

391+
exports.parse = (str) => {
392+
if (str.charAt(0) === '1') {
393+
// base58btc encoded public key
394+
return exports.createFromBytes(base58btc.decode(`z${str}`))
395+
}
396+
397+
// try to parse it as a regular base58btc multihash or base32 encoded CID
398+
return exports.createFromCID(CID.parse(str))
399+
}
400+
363401
exports.isPeerId = (peerId) => {
364402
return Boolean(typeof peerId === 'object' &&
365403
peerId._id &&

0 commit comments

Comments
 (0)