eth-sig-util
Advanced tools
Comparing version 1.2.2 to 1.3.0
39
index.js
const ethUtil = require('ethereumjs-util') | ||
const ethAbi = require('ethereumjs-abi') | ||
@@ -52,11 +53,41 @@ module.exports = { | ||
signTypedData: function (privateKey, msgParams) { | ||
const msgHash = typedSignatureHash(msgParams.data) | ||
const sig = ethUtil.ecsign(msgHash, privateKey) | ||
return ethUtil.bufferToHex(this.concatSig(sig.v, sig.r, sig.s)) | ||
}, | ||
recoverTypedSignature: function (msgParams) { | ||
const msgHash = typedSignatureHash(msgParams.data) | ||
const publicKey = recoverPublicKey(msgHash, msgParams.sig) | ||
const sender = ethUtil.publicToAddress(publicKey) | ||
return ethUtil.bufferToHex(sender) | ||
} | ||
} | ||
function typedSignatureHash(typedData) { | ||
const data = typedData.map(function (e) { return e.value }) | ||
const types = typedData.map(function (e) { return e.type }) | ||
const schema = typedData.map(function (e) { return `${e.type} ${e.name}` }) | ||
return ethAbi.soliditySHA3( | ||
['bytes32', 'bytes32'], | ||
[ | ||
ethAbi.soliditySHA3(new Array(typedData.length).fill('string'), schema), | ||
ethAbi.soliditySHA3(types, data) | ||
] | ||
) | ||
} | ||
function recoverPublicKey(hash, sig) { | ||
const signature = ethUtil.toBuffer(sig) | ||
const sigParams = ethUtil.fromRpcSig(signature) | ||
return ethUtil.ecrecover(hash, sigParams.v, sigParams.r, sigParams.s) | ||
} | ||
function getPublicKeyFor (msgParams) { | ||
const message = ethUtil.toBuffer(msgParams.data) | ||
const msgHash = ethUtil.hashPersonalMessage(message) | ||
const signature = ethUtil.toBuffer(msgParams.sig) | ||
const sigParams = ethUtil.fromRpcSig(signature) | ||
const publicKey = ethUtil.ecrecover(msgHash, sigParams.v, sigParams.r, sigParams.s) | ||
return publicKey | ||
return recoverPublicKey(msgHash, msgParams.sig) | ||
} | ||
@@ -63,0 +94,0 @@ |
{ | ||
"name": "eth-sig-util", | ||
"version": "1.2.2", | ||
"version": "1.3.0", | ||
"description": "A few useful functions for signing ethereum data", | ||
@@ -24,2 +24,3 @@ "main": "index.js", | ||
"dependencies": { | ||
"ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git", | ||
"ethereumjs-util": "^5.1.1" | ||
@@ -26,0 +27,0 @@ }, |
@@ -1,7 +0,18 @@ | ||
# Eth-Sig-Util [![CircleCI](https://circleci.com/gh/flyswatter/eth-sig-util.svg?style=svg)](https://circleci.com/gh/flyswatter/eth-sig-util) | ||
# Eth-Sig-Util [![CircleCI](https://circleci.com/gh/MetaMask/eth-sig-util.svg?style=svg)](https://circleci.com/gh/MetaMask/eth-sig-util) | ||
[![Greenkeeper badge](https://badges.greenkeeper.io/MetaMask/eth-sig-util.svg)](https://greenkeeper.io/) | ||
A small collection of ethereum signing functions. | ||
You can find usage examples [here](https://github.com/flyswatter/js-eth-personal-sign-examples) | ||
[Available on NPM](https://www.npmjs.com/package/eth-sig-util) | ||
## Supported Signing Methods | ||
Currently there is only one supported signing protocol. More will be added as standardized. | ||
- Personal Sign (`personal_sign`) [geth thread](https://github.com/ethereum/go-ethereum/pull/2940) | ||
## Installation | ||
@@ -37,2 +48,14 @@ | ||
### signTypedData (privateKeyBuffer, msgParams) | ||
Signs typed data as per [EIP712](https://github.com/ethereum/EIPs/pull/712). | ||
Data should be under `data` key of `msgParams`. The method returns prefixed signature. | ||
### recoverTypedSignature ({data, sig}) | ||
Return address of a signer that did `signTypedData`. | ||
Expects the same data that were used for signing. `sig` is a prefixed signature. | ||
### extractPublicKey (msgParams) | ||
@@ -39,0 +62,0 @@ |
const test = require('tape') | ||
const sigUtil = require('../') | ||
const ethUtil = require('ethereumjs-util') | ||
@@ -55,3 +54,2 @@ test('normalize address lower cases', function (t) { | ||
t.plan(1) | ||
const address = '0x29c76e6ad8f28bb1004902578fb108c507be341b' | ||
const privKeyHex = '4af1bceebf7f3634ec3cff8a2c38e51178d5d4ce585c52d6043e5e2cc3418bb0' | ||
@@ -71,2 +69,53 @@ const pubKeyHex = '0x9e9e45b2ec5f070b4e26f57c7fedf647afa7a03e894789816fbd12fedc5acd79d0dfeea925688e177caccb8f5e09f0c289bbcfc7adb98d76f5f8c5259478903a' | ||
test('signTypedData and recoverTypedSignature - single message', function (t) { | ||
t.plan(1) | ||
const address = '0x29c76e6ad8f28bb1004902578fb108c507be341b' | ||
const privKeyHex = '4af1bceebf7f3634ec3cff8a2c38e51178d5d4ce585c52d6043e5e2cc3418bb0' | ||
const privKey = Buffer.from(privKeyHex, 'hex') | ||
const typedData = [ | ||
{ | ||
type: 'string', | ||
name: 'message', | ||
value: 'Hi, Alice!' | ||
} | ||
] | ||
const msgParams = { data: typedData } | ||
const signature = sigUtil.signTypedData(privKey, msgParams) | ||
const recovered = sigUtil.recoverTypedSignature({ data: msgParams.data, sig: signature }) | ||
t.equal(address, recovered) | ||
}) | ||
test('signTypedData and recoverTypedSignature - multiple messages', function (t) { | ||
t.plan(1) | ||
const address = '0x29c76e6ad8f28bb1004902578fb108c507be341b' | ||
const privKeyHex = '4af1bceebf7f3634ec3cff8a2c38e51178d5d4ce585c52d6043e5e2cc3418bb0' | ||
const privKey = Buffer.from(privKeyHex, 'hex') | ||
const typedData = [ | ||
{ | ||
type: 'string', | ||
name: 'message', | ||
value: 'Hi, Alice!' | ||
}, | ||
{ | ||
type: 'uint8', | ||
name: 'value', | ||
value: 10 | ||
}, | ||
] | ||
const msgParams = { data: typedData } | ||
const signature = sigUtil.signTypedData(privKey, msgParams) | ||
const recovered = sigUtil.recoverTypedSignature({ data: msgParams.data, sig: signature }) | ||
t.equal(address, recovered) | ||
}) | ||
// personal_sign was declared without an explicit set of test data | ||
@@ -73,0 +122,0 @@ // so I made a script out of geth's internals to create this test data |
Git dependency
Supply chain riskContains a dependency which resolves to a remote git URL. Dependencies fetched from git URLs are not immutable can be used to inject untrusted code or reduce the likelihood of a reproducible install.
Found 1 instance in 1 package
11935
220
66
2
1