Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #149 from rmeissner/add_eth_signTypedData
Browse files Browse the repository at this point in the history
Add eth_signTypedData
  • Loading branch information
benjamincburns authored Aug 15, 2018
2 parents 81e8f59 + f695f1d commit e300dae
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 17 deletions.
30 changes: 30 additions & 0 deletions lib/statemanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ var BlockchainDouble = require("./blockchain_double.js");
var ForkedBlockchain = require("./utils/forkedblockchain.js");
var Web3 = require('web3');
var util = require("util");
var sigUtil = require('eth-sig-util')
var _ = require("lodash");

var to = require('./utils/to');
Expand Down Expand Up @@ -469,6 +470,35 @@ StateManager.prototype.sign = function(address, dataToSign) {
return utils.toRpcSig(sgn.v, sgn.r, sgn.s);
};

StateManager.prototype.signTypedData = function(address, typedDataToSign) {
var account = this.accounts[to.hex(address).toLowerCase()];
if (!account) {
throw new Error("cannot sign data; no private key");
}

if(!typedDataToSign.types) {
throw new Error("cannot sign data; types missing");
}

if(!typedDataToSign.types.EIP712Domain) {
throw new Error("cannot sign data; EIP712Domain definition missing");
}

if(!typedDataToSign.domain) {
throw new Error("cannot sign data; domain missing");
}

if(!typedDataToSign.primaryType) {
throw new Error("cannot sign data; primaryType missing");
}

if(!typedDataToSign.message) {
throw new Error("cannot sign data; message missing");
}

return sigUtil.signTypedData(account.secretKey, { data: typedDataToSign });
};

StateManager.prototype.printTransactionReceipt = function(tx_hash, error, callback){
var self = this;

Expand Down
13 changes: 13 additions & 0 deletions lib/subproviders/geth_api_double.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,19 @@ GethApiDouble.prototype.eth_sign = function(address, dataToSign, callback) {
callback(error, result);
};

GethApiDouble.prototype.eth_signTypedData = function(address, typedDataToSign, callback) {
var result;
var error;

try {
result = this.state.signTypedData(address, typedDataToSign);
} catch (e) {
error = e;
}

callback(error, result);
};

GethApiDouble.prototype.eth_sendTransaction = function(tx_data, callback) {
this.state.queueTransaction("eth_sendTransaction", tx_data, null, callback);
};
Expand Down
19 changes: 4 additions & 15 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"lib": "./lib"
},
"scripts": {
"test": "mocha --check-leaks --globals _scratch"
"test": "mocha --check-leaks --globals _scratch,sanitizedData"
},
"dependencies": {
"abstract-leveldown": "^3.0.0",
Expand All @@ -19,6 +19,7 @@
"cachedown": "^1.0.0",
"chai": "^3.5.0",
"clone": "^2.1.1",
"eth-sig-util": "^2.0.2",
"ethereumjs-account": "~2.0.4",
"ethereumjs-block": "~1.2.2",
"ethereumjs-tx": "1.3.4",
Expand Down
55 changes: 54 additions & 1 deletion test/requests.js
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,59 @@ var tests = function(web3) {

});

describe("eth_signTypedData", function() {
var accounts;
var signingWeb3;

// Account based on https://github.com/ethereum/EIPs/blob/master/assets/eip-712/Example.js
var acc = {
balance: "0x00",
secretKey: web3.utils.sha3('cow')
};

// Load account.
before(function( done ){
signingWeb3 = new Web3();
signingWeb3.setProvider(Ganache.provider({
accounts: [ acc ]
}));
signingWeb3.eth.getAccounts(function(err, accs) {
if (err) return done(err);
accounts = accs.map(function(val) {
return val.toLowerCase();
});
done();
});
});

it("should produce a signature whose signer can be recovered", function(done) {
var typedData = {"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"Person":[{"name":"name","type":"string"},{"name":"wallet","type":"address"}],"Mail":[{"name":"from","type":"Person"},{"name":"to","type":"Person"},{"name":"contents","type":"string"}]},"primaryType":"Mail","domain":{"name":"Ether Mail","version":"1","chainId":1,"verifyingContract":"0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"},"message":{"from":{"name":"Cow","wallet":"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"},"to":{"name":"Bob","wallet":"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"},"contents":"Hello, Bob!"}}
var msg = utils.toBuffer("asparagus");
var msgHash = utils.hashPersonalMessage(msg);

signingWeb3.currentProvider.sendAsync({
jsonrpc: "2.0",
method: "eth_signTypedData",
params: [accounts[0], typedData],
id: new Date().getTime()
}, function(err, response) {
if (err) {
return done(err);
}
console.log(response);
assert.equal(response.result, "0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c");
done();
});
});

after("shutdown", function(done) {
let provider = signingWeb3._provider;
signingWeb3.setProvider()
provider.close(done)
});

});

describe('eth_sendRawTransaction', () => {

it("should fail with bad nonce (too low)", function(done) {
Expand Down Expand Up @@ -1278,7 +1331,7 @@ describe("WebSockets Server:", function(done) {
});
server.listen(port, function(err) {
var provider = new Web3WsProvider("ws://localhost:" + port);
var Web3 = require('web3');
var Web3 = require('web3');
web3.setProvider(provider);
done();
});
Expand Down

0 comments on commit e300dae

Please sign in to comment.