Skip to content

Commit

Permalink
feat: async await
Browse files Browse the repository at this point in the history
License: MIT
Signed-off-by: Henrique Dias <hacdias@gmail.com>
  • Loading branch information
hacdias committed Oct 30, 2018
1 parent eb06275 commit 97ed4ac
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 347 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ language: node_js

matrix:
include:
- node_js: 6
env: CXX=g++-4.8
- node_js: 8
env: CXX=g++-4.8
- node_js: 10
env: CXX=g++-4.8
# - node_js: stable
# env: CXX=g++-4.8

Expand Down
26 changes: 18 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
- [API](#api)
- [Create](#create)
- [`new PeerId(id[, privKey, pubKey])`](#new-peeridid-privkey-pubkey)
- [`create([opts], callback)`](#createopts-callback)
- [`create([opts])`](#createopts)
- [Import](#import)
- [`createFromHexString(str)`](#createfromhexstringstr)
- [`createFromBytes(buf)`](#createfrombytesbuf)
Expand Down Expand Up @@ -57,11 +57,10 @@ The public key is a base64 encoded string of a protobuf containing an RSA DER bu
```JavaScript
const PeerId = require('peer-id')

PeerId.create({ bits: 1024 }, (err, id) => {
if (err) { throw err }
console.log(JSON.stringify(id.toJSON(), null, 2))
})
const id = await PeerId.create({ bits: 1024 })
console.log(JSON.stringify(id.toJSON(), null, 2))
```

```bash
{
"id": "Qma9T5YraSnpRDZqRR4krcSJabThc8nwZuJV3LercPHufi",
Expand Down Expand Up @@ -124,47 +123,58 @@ const PeerId = require('peer-id')

The key format is detailed in [libp2p-crypto](https://github.com/libp2p/js-libp2p-crypto).

### `create([opts], callback)`
### `create([opts])`

Generates a new Peer ID, complete with public/private keypair.

- `opts: Object`: Default: `{bits: 2048}`
- `callback: Function`

Calls back `callback` with `err, id`.
Returns `Promise<PeerId>`.

## Import

### `createFromHexString(str)`

Creates a Peer ID from hex string representing the key's multihash.

Returns `Promise<PeerId>`.

### `createFromBytes(buf)`

Creates a Peer ID from a buffer representing the key's multihash.

Returns `Promise<PeerId>`.

### `createFromB58String(str)`

Creates a Peer ID from a Base58 string representing the key's multihash.

Returns `Promise<PeerId>`.

### `createFromPubKey(pubKey)`

- `publicKey: Buffer`

Creates a Peer ID from a buffer containing a public key.

Returns `Promise<PeerId>`.

### `createFromPrivKey(privKey)`

- `privKey: Buffer`

Creates a Peer ID from a buffer containing a private key.

Returns `Promise<PeerId>`.

### `createFromJSON(obj)`

- `obj.id: String` - The multihash encoded in `base58`
- `obj.pubKey: String` - The public key in protobuf format, encoded in `base64`
- `obj.privKey: String` - The private key in protobuf format, encoded in `base64`

Returns `Promise<PeerId>`.

## Export

### `toHexString()`
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ version: "{build}"

environment:
matrix:
- nodejs_version: "6"
- nodejs_version: "8"
- nodejs_version: "10"

matrix:
fast_finish: true
Expand Down
11 changes: 5 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,15 @@
},
"homepage": "https://github.com/libp2p/js-peer-id",
"devDependencies": {
"aegir": "^14.0.0",
"chai": "^4.1.2",
"aegir": "^17.0.0",
"chai": "^4.2.0",
"dirty-chai": "^2.0.1"
},
"dependencies": {
"async": "^2.6.1",
"class-is": "^1.1.0",
"libp2p-crypto": "~0.13.0",
"lodash": "^4.17.10",
"multihashes": "~0.4.13"
"libp2p-crypto": "libp2p/js-libp2p-crypto#371bd05",
"lodash": "^4.17.11",
"multihashes": "~0.4.14"
},
"repository": {
"type": "git",
Expand Down
11 changes: 5 additions & 6 deletions src/bin.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@

const PeerId = require('./index.js')

PeerId.create((err, id) => {
if (err) {
throw err
}
async function main () {
const id = await PeerId.create()
console.log(JSON.stringify(id.toJSON(), null, 1))
}

console.log(JSON.stringify(id.toJSON(), null, 2))
})
main()
174 changes: 56 additions & 118 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
const mh = require('multihashes')
const crypto = require('libp2p-crypto')
const assert = require('assert')
const waterfall = require('async/waterfall')
const withIs = require('class-is')

class PeerId {
Expand Down Expand Up @@ -119,176 +118,115 @@ class PeerId {
/*
* Check if this PeerId instance is valid (privKey -> pubKey -> Id)
*/
isValid (callback) {
isValid () {
// TODO Needs better checking
if (this.privKey &&
this.privKey.public &&
this.privKey.public.bytes &&
Buffer.isBuffer(this.pubKey.bytes) &&
this.privKey.public.bytes.equals(this.pubKey.bytes)) {
callback()
return true
} else {
callback(new Error('Keys not match'))
throw new Error('Keys not match')
}
}
}

const PeerIdWithIs = withIs(PeerId, { className: 'PeerId', symbolName: '@libp2p/js-peer-id/PeerId' })
const PeerIdWithIs = withIs(PeerId, {
className: 'PeerId',
symbolName: '@libp2p/js-peer-id/PeerId'
})

exports = module.exports = PeerIdWithIs

// generation
exports.create = function (opts, callback) {
if (typeof opts === 'function') {
callback = opts
opts = {}
}
exports.create = async (opts) => {
opts = opts || {}
opts.bits = opts.bits || 2048

waterfall([
(cb) => crypto.keys.generateKeyPair('RSA', opts.bits, cb),
(privKey, cb) => privKey.public.hash((err, digest) => {
cb(err, digest, privKey)
})
], (err, digest, privKey) => {
if (err) {
return callback(err)
}
const key = await crypto.keys.generateKeyPair('RSA', opts.bits)
const digest = await key.public.hash()

callback(null, new PeerIdWithIs(digest, privKey))
})
return new PeerIdWithIs(digest, key)
}

exports.createFromHexString = function (str) {
exports.createFromHexString = async (str) => {
return new PeerIdWithIs(mh.fromHexString(str))
}

exports.createFromBytes = function (buf) {
exports.createFromBytes = async (buf) => {
return new PeerIdWithIs(buf)
}

exports.createFromB58String = function (str) {
exports.createFromB58String = async (str) => {
return new PeerIdWithIs(mh.fromB58String(str))
}

// Public Key input will be a buffer
exports.createFromPubKey = function (key, callback) {
if (typeof callback !== 'function') {
throw new Error('callback is required')
}

let pubKey

try {
let buf = key
if (typeof buf === 'string') {
buf = Buffer.from(key, 'base64')
}

if (!Buffer.isBuffer(buf)) throw new Error('Supplied key is neither a base64 string nor a buffer')
exports.createFromPubKey = async (key) => {
let buf = key

pubKey = crypto.keys.unmarshalPublicKey(buf)
} catch (err) {
return callback(err)
if (typeof buf === 'string') {
buf = Buffer.from(key, 'base64')
}

pubKey.hash((err, digest) => {
if (err) {
return callback(err)
}
if (!Buffer.isBuffer(buf)) {
throw new Error('Supplied key is neither a base64 string nor a buffer')
}

callback(null, new PeerIdWithIs(digest, null, pubKey))
})
const pubKey = await crypto.keys.unmarshalPublicKey(buf)
const digest = await pubKey.hash()
return new PeerIdWithIs(digest, null, pubKey)
}

// Private key input will be a string
exports.createFromPrivKey = function (key, callback) {
if (typeof callback !== 'function') {
throw new Error('callback is required')
}

exports.createFromPrivKey = async (key) => {
let buf = key

try {
if (typeof buf === 'string') {
buf = Buffer.from(key, 'base64')
}
if (typeof buf === 'string') {
buf = Buffer.from(key, 'base64')
}

if (!Buffer.isBuffer(buf)) throw new Error('Supplied key is neither a base64 string nor a buffer')
} catch (err) {
return callback(err)
if (!Buffer.isBuffer(buf)) {
throw new Error('Supplied key is neither a base64 string nor a buffer')
}

waterfall([
(cb) => crypto.keys.unmarshalPrivateKey(buf, cb),
(privKey, cb) => privKey.public.hash((err, digest) => {
cb(err, digest, privKey)
})
], (err, digest, privKey) => {
if (err) {
return callback(err)
}
const privKey = await crypto.keys.unmarshalPrivateKey(buf)
const digest = await privKey.public.hash()

callback(null, new PeerIdWithIs(digest, privKey, privKey.public))
})
return new PeerIdWithIs(digest, privKey, privKey.public)
}

exports.createFromJSON = function (obj, callback) {
if (typeof callback !== 'function') {
throw new Error('callback is required')
exports.createFromJSON = async (obj) => {
let id = mh.fromB58String(obj.id)
let rawPrivKey = obj.privKey && Buffer.from(obj.privKey, 'base64')
let rawPubKey = obj.pubKey && Buffer.from(obj.pubKey, 'base64')
let pub = rawPubKey && await crypto.keys.unmarshalPublicKey(rawPubKey)

if (!rawPrivKey) {
return new PeerIdWithIs(id, null, pub)
}

let id
let rawPrivKey
let rawPubKey
let pub

try {
id = mh.fromB58String(obj.id)
rawPrivKey = obj.privKey && Buffer.from(obj.privKey, 'base64')
rawPubKey = obj.pubKey && Buffer.from(obj.pubKey, 'base64')
pub = rawPubKey && crypto.keys.unmarshalPublicKey(rawPubKey)
} catch (err) {
return callback(err)
const privKey = await crypto.keys.unmarshalPrivateKey(rawPrivKey)
const privDigest = await privKey.public.hash()
let pubDigest

if (pub) {
pubDigest = await pub.hash()
}

if (rawPrivKey) {
waterfall([
(cb) => crypto.keys.unmarshalPrivateKey(rawPrivKey, cb),
(priv, cb) => priv.public.hash((err, digest) => {
cb(err, digest, priv)
}),
(privDigest, priv, cb) => {
if (pub) {
pub.hash((err, pubDigest) => {
cb(err, privDigest, priv, pubDigest)
})
} else {
cb(null, privDigest, priv)
}
}
], (err, privDigest, priv, pubDigest) => {
if (err) {
return callback(err)
}

if (pub && !privDigest.equals(pubDigest)) {
return callback(new Error('Public and private key do not match'))
}

if (id && !privDigest.equals(id)) {
return callback(new Error('Id and private key do not match'))
}

callback(null, new PeerIdWithIs(id, priv, pub))
})
} else {
callback(null, new PeerIdWithIs(id, null, pub))
if (pub && !privDigest.equals(pubDigest)) {
throw new Error('Public and private key do not match')
}

if (id && !privDigest.equals(id)) {
throw new Error('Id and private key do not match')
}

return new PeerIdWithIs(id, privKey, pub)
}

exports.isPeerId = function (peerId) {
exports.isPeerId = (peerId) => {
return Boolean(typeof peerId === 'object' &&
peerId._id &&
peerId._idB58String)
Expand Down
Loading

0 comments on commit 97ed4ac

Please sign in to comment.