From adcfaa2e80389f69e196b602955cee858a1eb40f Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Mon, 1 Oct 2018 20:37:13 +1000 Subject: Expose eth_signTypedData functionality for order signing --- packages/order-utils/src/signature_utils.ts | 50 ++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'packages/order-utils/src/signature_utils.ts') diff --git a/packages/order-utils/src/signature_utils.ts b/packages/order-utils/src/signature_utils.ts index 3b656d3fc..05c673ae2 100644 --- a/packages/order-utils/src/signature_utils.ts +++ b/packages/order-utils/src/signature_utils.ts @@ -1,5 +1,5 @@ import { schemas } from '@0xproject/json-schemas'; -import { ECSignature, SignatureType, SignerType, ValidatorSignature } from '@0xproject/types'; +import { ECSignature, Order, SignatureType, SignerType, ValidatorSignature } from '@0xproject/types'; import { Web3Wrapper } from '@0xproject/web3-wrapper'; import { Provider } from 'ethereum-types'; import * as ethUtil from 'ethereumjs-util'; @@ -7,9 +7,11 @@ import * as _ from 'lodash'; import { artifacts } from './artifacts'; import { assert } from './assert'; +import { EIP712_DOMAIN_NAME, EIP712_DOMAIN_SCHEMA, EIP712_DOMAIN_VERSION } from './eip712_utils'; import { ExchangeContract } from './generated_contract_wrappers/exchange'; import { IValidatorContract } from './generated_contract_wrappers/i_validator'; import { IWalletContract } from './generated_contract_wrappers/i_wallet'; +import { EIP712_ORDER_SCHEMA } from './order_hash'; import { OrderError } from './types'; import { utils } from './utils'; @@ -191,6 +193,52 @@ export const signatureUtils = { return false; } }, + /** + * Signs an order using `eth_signTypedData` and returns it's elliptic curve signature and signature type. + * This method currently supports Ganache. + * @param order The Order to sign. + * @param signerAddress The hex encoded Ethereum address you wish to sign it with. This address + * must be available via the Provider supplied to 0x.js. + * @return A hex encoded string containing the Elliptic curve signature generated by signing the orderHash and the Signature Type. + */ + async ecSignOrderAsync(provider: Provider, order: Order, signerAddress: string): Promise { + assert.isWeb3Provider('provider', provider); + assert.isETHAddressHex('signerAddress', signerAddress); + const web3Wrapper = new Web3Wrapper(provider); + await assert.isSenderAddressAsync('signerAddress', signerAddress, web3Wrapper); + const normalizedSignerAddress = signerAddress.toLowerCase(); + const typedData = { + types: { + EIP712Domain: EIP712_DOMAIN_SCHEMA.parameters, + Order: EIP712_ORDER_SCHEMA.parameters, + }, + domain: { + name: EIP712_DOMAIN_NAME, + version: EIP712_DOMAIN_VERSION, + verifyingContract: order.exchangeAddress, + }, + message: { + ...order, + salt: order.salt.toString(), + makerFee: order.makerFee.toString(), + takerFee: order.takerFee.toString(), + makerAssetAmount: order.makerAssetAmount.toString(), + takerAssetAmount: order.takerAssetAmount.toString(), + expirationTimeSeconds: order.expirationTimeSeconds.toString(), + }, + primaryType: 'Order', + }; + const signature = await web3Wrapper.signTypedDataAsync(normalizedSignerAddress, typedData); + const ecSignatureRSV = parseSignatureHexAsRSV(signature); + const signatureBuffer = Buffer.concat([ + ethUtil.toBuffer(ecSignatureRSV.v), + ethUtil.toBuffer(ecSignatureRSV.r), + ethUtil.toBuffer(ecSignatureRSV.s), + ethUtil.toBuffer(SignatureType.EIP712), + ]); + const signatureHex = `0x${signatureBuffer.toString('hex')}`; + return signatureHex; + }, /** * Signs an orderHash and returns it's elliptic curve signature and signature type. * This method currently supports TestRPC, Geth and Parity above and below V1.6.6 -- cgit v1.2.3