aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabio Berger <me@fabioberger.com>2017-05-29 19:37:08 +0800
committerFabio Berger <me@fabioberger.com>2017-05-29 19:37:08 +0800
commiteb90367fc4fc666786398ab9803b77bfb900c661 (patch)
tree711e4e92060828508e22d6cace759a4d47ad1ec4
parent232e03195974403878f303a59f0ff8669b54f205 (diff)
downloaddexon-0x-contracts-eb90367fc4fc666786398ab9803b77bfb900c661.tar.gz
dexon-0x-contracts-eb90367fc4fc666786398ab9803b77bfb900c661.tar.zst
dexon-0x-contracts-eb90367fc4fc666786398ab9803b77bfb900c661.zip
Port over signOrderHashAsync
-rw-r--r--package.json2
-rw-r--r--src/0x.js.ts64
-rw-r--r--src/globals.d.ts3
-rw-r--r--src/types.ts1
-rw-r--r--src/utils/utils.ts4
5 files changed, 73 insertions, 1 deletions
diff --git a/package.json b/package.json
index 5c352bc88..a191d4b73 100644
--- a/package.json
+++ b/package.json
@@ -68,9 +68,11 @@
},
"dependencies": {
"bignumber.js": "^4.0.2",
+ "compare-versions": "^3.0.1",
"es6-promisify": "^5.0.0",
"ethereumjs-abi": "^0.6.4",
"ethereumjs-util": "^5.1.1",
+ "find-versions": "^2.0.0",
"jsonschema": "^1.1.1",
"lodash": "^4.17.4",
"truffle-contract": "^2.0.0",
diff --git a/src/0x.js.ts b/src/0x.js.ts
index de082146f..eff371c3b 100644
--- a/src/0x.js.ts
+++ b/src/0x.js.ts
@@ -8,9 +8,11 @@ import {Web3Wrapper} from './web3_wrapper';
import {constants} from './utils/constants';
import {utils} from './utils/utils';
import {assert} from './utils/assert';
+import findVersions = require('find-versions');
+import compareVersions = require('compare-versions');
import {ExchangeWrapper} from './contract_wrappers/exchange_wrapper';
import {ECSignatureSchema} from './schemas/ec_signature_schema';
-import {SolidityTypes, ECSignature} from './types';
+import {SolidityTypes, ECSignature, ZeroExError} from './types';
const MAX_DIGITS_IN_UNSIGNED_256_INT = 78;
@@ -131,4 +133,64 @@ export class ZeroEx {
this.web3Wrapper = new Web3Wrapper(web3);
this.exchange = new ExchangeWrapper(this.web3Wrapper);
}
+ /**
+ * Signs an orderHash and returns it's ECSignature
+ * This method currently supports TestRPC, Geth and Parity above and below V1.6.6
+ */
+ public async signOrderHashAsync(orderHashHex: string): Promise<ECSignature> {
+ assert.isHexString('orderHashHex', orderHashHex);
+
+ let msgHashHex;
+ const nodeVersion = await this.web3Wrapper.getNodeVersionAsync();
+ const isParityNode = utils.isParityNode(nodeVersion);
+ if (isParityNode) {
+ // Parity node adds the personalMessage prefix itself
+ msgHashHex = orderHashHex;
+ } else {
+ const orderHashBuff = ethUtil.toBuffer(orderHashHex);
+ const msgHashBuff = ethUtil.hashPersonalMessage(orderHashBuff);
+ msgHashHex = ethUtil.bufferToHex(msgHashBuff);
+ }
+
+ const makerAddressIfExists = await this.web3Wrapper.getSenderAddressIfExistsAsync();
+ if (_.isUndefined(makerAddressIfExists)) {
+ throw new Error(ZeroExError.USER_HAS_NO_ASSOCIATED_ADDRESSES);
+ }
+
+ const signature = await this.web3Wrapper.signTransactionAsync(makerAddressIfExists, msgHashHex);
+
+ let signatureData;
+ const [nodeVersionNumber] = findVersions(nodeVersion);
+ // Parity v1.6.6 and earlier returns the signatureData as vrs instead of rsv as Geth does
+ // Later versions return rsv but for the time being we still want to support version < 1.6.6
+ // Date: May 23rd 2017
+ const latestParityVersionWithVRS = '1.6.6';
+ const isVersionBeforeParityFix = compareVersions(nodeVersionNumber, latestParityVersionWithVRS) <= 0;
+ if (isParityNode && isVersionBeforeParityFix) {
+ const signatureBuffer = ethUtil.toBuffer(signature);
+ let v = signatureBuffer[0];
+ if (v < 27) {
+ v += 27;
+ }
+ signatureData = {
+ v,
+ r: signatureBuffer.slice(1, 33),
+ s: signatureBuffer.slice(33, 65),
+ };
+ } else {
+ signatureData = ethUtil.fromRpcSig(signature);
+ }
+
+ const {v, r, s} = signatureData;
+ const ecSignature: ECSignature = {
+ v,
+ r: ethUtil.bufferToHex(r),
+ s: ethUtil.bufferToHex(s),
+ };
+ const isValidSignature = ZeroEx.isValidSignature(orderHashHex, ecSignature, makerAddressIfExists);
+ if (!isValidSignature) {
+ throw new Error(ZeroExError.INVALID_SIGNATURE);
+ }
+ return ecSignature;
+ }
}
diff --git a/src/globals.d.ts b/src/globals.d.ts
index dee957f2f..78b768dd1 100644
--- a/src/globals.d.ts
+++ b/src/globals.d.ts
@@ -3,6 +3,8 @@ declare module 'bn.js';
declare module 'request-promise-native';
declare module 'web3-provider-engine';
declare module 'web3-provider-engine/subproviders/rpc';
+declare module 'find-versions';
+declare module 'compare-versions';
declare interface Schema {
id: string;
@@ -35,6 +37,7 @@ declare module 'ethereumjs-util' {
const pubToAddress: (pubKey: string) => Buffer;
const isValidAddress: (address: string) => boolean;
const bufferToInt: (buffer: Buffer) => number;
+ const fromRpcSig: (signature: string) => {v: number, r: Buffer, s: Buffer};
}
// truffle-contract declarations
diff --git a/src/types.ts b/src/types.ts
index 4da03a4d3..3bed01547 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -13,6 +13,7 @@ export const ZeroExError = strEnum([
'CONTRACT_DOES_NOT_EXIST',
'UNHANDLED_ERROR',
'USER_HAS_NO_ASSOCIATED_ADDRESSES',
+ 'INVALID_SIGNATURE',
]);
export type ZeroExError = keyof typeof ZeroExError;
diff --git a/src/utils/utils.ts b/src/utils/utils.ts
index b514b702d..2098a67b3 100644
--- a/src/utils/utils.ts
+++ b/src/utils/utils.ts
@@ -1,3 +1,4 @@
+import * as _ from 'lodash';
import * as BN from 'bn.js';
export const utils = {
@@ -15,4 +16,7 @@ export const utils = {
console.log(message);
/* tslint:enable */
},
+ isParityNode(nodeVersion: string): boolean {
+ return _.includes(nodeVersion, 'Parity');
+ },
};