Skip to content

Commit

Permalink
Support instantation with public keys
Browse files Browse the repository at this point in the history
  • Loading branch information
axic committed Mar 23, 2016
1 parent 155513d commit ecbf109
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 6 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ Features not supported:
Constructors:

* `generate([icap])` - create an instance based on a new random key (setting `icap` to true will generate an address suitable for the `ICAP Direct mode`)
* `fromPrivateKey(input)` - create an instance based on a raw key
* `fromPrivateKey(input)` - create an instance based on a raw private key
* `fromPublicKey(input)` - create an instance based on a public key (certain methods will not be available)
* `fromV1(input, password)` - import a wallet (Version 1 of the Ethereum wallet format)
* `fromV3(input, password, [nonStrict])` - import a wallet (Version 3 of the Ethereum wallet format). Set `nonStrict` true to accept files with mixed-caps.
* `fromEthSale(input, password)` - import an Ethereum Pre Sale wallet
Expand Down
33 changes: 28 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,30 @@ function decipherBuffer (decipher, data) {
return Buffer.concat([ decipher.update(data), decipher.final() ])
}

var Wallet = function (priv) {
if (!ethUtil.isValidPrivate(priv)) {
var Wallet = function (priv, pub) {
if (priv && !ethUtil.isValidPrivate(priv)) {
throw new Error('Private key does not satisfy the curve requirements (ie. it is invalid)')
}
this.privKey = priv
this._privKey = priv
this._pubKey = pub
}

Object.defineProperty(Wallet.prototype, 'privKey', {
get: function () {
assert(this._privKey, 'This is a public key only wallet')
return this._privKey
}
})

Object.defineProperty(Wallet.prototype, 'pubKey', {
get: function () {
if (!this._pubKey) {
this._pubKey = ethUtil.privateToPublic(this.privKey)
}
return this._pubKey
}
})

Wallet.generate = function (icapDirect) {
if (icapDirect) {
while (true) {
Expand All @@ -42,15 +59,15 @@ Wallet.prototype.getPrivateKeyString = function () {
}

Wallet.prototype.getPublicKey = function () {
return ethUtil.privateToPublic(this.privKey)
return this.pubKey
}

Wallet.prototype.getPublicKeyString = function () {
return ethUtil.bufferToHex(this.getPublicKey())
}

Wallet.prototype.getAddress = function () {
return ethUtil.privateToAddress(this.privKey)
return ethUtil.publicToAddress(this.pubKey)
}

Wallet.prototype.getAddressString = function () {
Expand All @@ -63,6 +80,8 @@ Wallet.prototype.getChecksumAddressString = function () {

// https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition
Wallet.prototype.toV3 = function (password, opts) {
assert(this._privKey, 'This is a public key only wallet')

opts = opts || {}
var salt = opts.salt || crypto.randomBytes(32)
var iv = opts.iv || crypto.randomBytes(16)
Expand Down Expand Up @@ -140,6 +159,10 @@ Wallet.prototype.toV3String = function (password, opts) {
return JSON.stringify(this.toV3(password, opts))
}

Wallet.fromPublicKey = function (pub) {
return new Wallet(null, pub)
}

Wallet.fromPrivateKey = function (priv) {
return new Wallet(priv)
}
Expand Down
21 changes: 21 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,27 @@ describe('.getChecksumAddressString()', function () {
})
})

describe('public key only wallet', function () {
var pubKey = new Buffer('5d4392f450262b276652c1fc037606abac500f3160830ce9df53aa70d95ce7cfb8b06010b2f3691c78c65c21eb4cf3dfdbfc0745d89b664ee10435bb3a0f906c', 'hex')
it('.fromPublicKey() should work', function () {
assert.equal(Wallet.fromPublicKey(pubKey).getPublicKey().toString('hex'),
'5d4392f450262b276652c1fc037606abac500f3160830ce9df53aa70d95ce7cfb8b06010b2f3691c78c65c21eb4cf3dfdbfc0745d89b664ee10435bb3a0f906c')
})
it('.getAddress() should work', function () {
assert.equal(Wallet.fromPublicKey(pubKey).getAddress().toString('hex'), 'b14ab53e38da1c172f877dbc6d65e4a1b0474c3c')
})
it('.getPrivateKey() should fail', function () {
assert.throws(function () {
Wallet.fromPublicKey(pubKey).getPrivateKey()
})
})
it('.toV3() should fail', function () {
assert.throws(function () {
Wallet.fromPublicKey(pubKey).toV3()
})
})
})

describe('.generate()', function () {
it('should generate an account', function () {
assert.equal(Wallet.generate().getPrivateKey().length, 32)
Expand Down

0 comments on commit ecbf109

Please sign in to comment.