aboutsummaryrefslogtreecommitdiffstats
path: root/packages/order-utils/src/signature_utils.ts
diff options
context:
space:
mode:
authorBrandon Millman <brandon.millman@gmail.com>2018-08-24 01:58:33 +0800
committerBrandon Millman <brandon.millman@gmail.com>2018-08-24 01:58:33 +0800
commit57c104119c409c053eb977553c92341c3ca83afd (patch)
tree7f1129fd01001604e7412e33ccef202c1ff90612 /packages/order-utils/src/signature_utils.ts
parentcd5c73550b969fe0a87524143ce617749935427a (diff)
parent6e27324a341801e1a2d8d6989d749dfe021ae39b (diff)
downloaddexon-sol-tools-57c104119c409c053eb977553c92341c3ca83afd.tar
dexon-sol-tools-57c104119c409c053eb977553c92341c3ca83afd.tar.gz
dexon-sol-tools-57c104119c409c053eb977553c92341c3ca83afd.tar.bz2
dexon-sol-tools-57c104119c409c053eb977553c92341c3ca83afd.tar.lz
dexon-sol-tools-57c104119c409c053eb977553c92341c3ca83afd.tar.xz
dexon-sol-tools-57c104119c409c053eb977553c92341c3ca83afd.tar.zst
dexon-sol-tools-57c104119c409c053eb977553c92341c3ca83afd.zip
Merge branch 'development' into feature/forwarder-helper/init
* development: (187 commits) Remove trailing slash Fix linter Stop nesting interfaces and add necessary type exports Remove duplicate type and remove nested interface Add support for rending the Tuple type Add missing keyu Remove excessive timestamp Improve doc commebnt Remove docs catch-all endpoint Fix comments Look for all TS mapped types Add catch and exit with non-zero Remove superfluous dep Fix CHANGELOG entry Fix double assignment Upgrade Typedoc to 0.12.0, which works with TS 3.x Fix prettier issues Enable dry run of release publishing and handle git tags existing update yarn.lock Missing/superfluous type exports from connect ...
Diffstat (limited to 'packages/order-utils/src/signature_utils.ts')
-rw-r--r--packages/order-utils/src/signature_utils.ts626
1 files changed, 325 insertions, 301 deletions
diff --git a/packages/order-utils/src/signature_utils.ts b/packages/order-utils/src/signature_utils.ts
index 870aef2ed..40bbcef98 100644
--- a/packages/order-utils/src/signature_utils.ts
+++ b/packages/order-utils/src/signature_utils.ts
@@ -13,329 +13,353 @@ import { IWalletContract } from './generated_contract_wrappers/i_wallet';
import { OrderError } from './types';
import { utils } from './utils';
-/**
- * Verifies that the provided signature is valid according to the 0x Protocol smart contracts
- * @param data The hex encoded data signed by the supplied signature.
- * @param signature A hex encoded 0x Protocol signature made up of: [TypeSpecificData][SignatureType].
- * E.g [vrs][SignatureType.EIP712]
- * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
- * @return Whether the signature is valid for the supplied signerAddress and data.
- */
-export async function isValidSignatureAsync(
- provider: Provider,
- data: string,
- signature: string,
- signerAddress: string,
-): Promise<boolean> {
- assert.isWeb3Provider('provider', provider);
- assert.isHexString('data', data);
- assert.isHexString('signature', signature);
- assert.isETHAddressHex('signerAddress', signerAddress);
- const signatureTypeIndexIfExists = utils.getSignatureTypeIndexIfExists(signature);
- if (_.isUndefined(signatureTypeIndexIfExists)) {
- throw new Error(`Unrecognized signatureType in signature: ${signature}`);
- }
-
- switch (signatureTypeIndexIfExists) {
- case SignatureType.Illegal:
- case SignatureType.Invalid:
- return false;
-
- case SignatureType.EIP712: {
- const ecSignature = parseECSignature(signature);
- return isValidECSignature(data, ecSignature, signerAddress);
+export const signatureUtils = {
+ /**
+ * Verifies that the provided signature is valid according to the 0x Protocol smart contracts
+ * @param data The hex encoded data signed by the supplied signature.
+ * @param signature A hex encoded 0x Protocol signature made up of: [TypeSpecificData][SignatureType].
+ * E.g [vrs][SignatureType.EIP712]
+ * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
+ * @return Whether the signature is valid for the supplied signerAddress and data.
+ */
+ async isValidSignatureAsync(
+ provider: Provider,
+ data: string,
+ signature: string,
+ signerAddress: string,
+ ): Promise<boolean> {
+ assert.isWeb3Provider('provider', provider);
+ assert.isHexString('data', data);
+ assert.isHexString('signature', signature);
+ assert.isETHAddressHex('signerAddress', signerAddress);
+ const signatureTypeIndexIfExists = utils.getSignatureTypeIndexIfExists(signature);
+ if (_.isUndefined(signatureTypeIndexIfExists)) {
+ throw new Error(`Unrecognized signatureType in signature: ${signature}`);
}
- case SignatureType.EthSign: {
- const ecSignature = parseECSignature(signature);
- const prefixedMessageHex = addSignedMessagePrefix(data, SignerType.Default);
- return isValidECSignature(prefixedMessageHex, ecSignature, signerAddress);
- }
+ switch (signatureTypeIndexIfExists) {
+ case SignatureType.Illegal:
+ case SignatureType.Invalid:
+ return false;
- case SignatureType.Caller:
- // HACK: We currently do not "validate" the caller signature type.
- // It can only be validated during Exchange contract execution.
- throw new Error('Caller signature type cannot be validated off-chain');
+ case SignatureType.EIP712: {
+ const ecSignature = signatureUtils.parseECSignature(signature);
+ return signatureUtils.isValidECSignature(data, ecSignature, signerAddress);
+ }
- case SignatureType.Wallet: {
- const isValid = await isValidWalletSignatureAsync(provider, data, signature, signerAddress);
- return isValid;
- }
+ case SignatureType.EthSign: {
+ const ecSignature = signatureUtils.parseECSignature(signature);
+ const prefixedMessageHex = signatureUtils.addSignedMessagePrefix(data, SignerType.Default);
+ return signatureUtils.isValidECSignature(prefixedMessageHex, ecSignature, signerAddress);
+ }
- case SignatureType.Validator: {
- const isValid = await isValidValidatorSignatureAsync(provider, data, signature, signerAddress);
- return isValid;
- }
+ case SignatureType.Caller:
+ // HACK: We currently do not "validate" the caller signature type.
+ // It can only be validated during Exchange contract execution.
+ throw new Error('Caller signature type cannot be validated off-chain');
- case SignatureType.PreSigned: {
- return isValidPresignedSignatureAsync(provider, data, signerAddress);
- }
+ case SignatureType.Wallet: {
+ const isValid = await signatureUtils.isValidWalletSignatureAsync(
+ provider,
+ data,
+ signature,
+ signerAddress,
+ );
+ return isValid;
+ }
- case SignatureType.Trezor: {
- const prefixedMessageHex = addSignedMessagePrefix(data, SignerType.Trezor);
- const ecSignature = parseECSignature(signature);
- return isValidECSignature(prefixedMessageHex, ecSignature, signerAddress);
- }
+ case SignatureType.Validator: {
+ const isValid = await signatureUtils.isValidValidatorSignatureAsync(
+ provider,
+ data,
+ signature,
+ signerAddress,
+ );
+ return isValid;
+ }
- default:
- throw new Error(`Unhandled SignatureType: ${signatureTypeIndexIfExists}`);
- }
-}
+ case SignatureType.PreSigned: {
+ return signatureUtils.isValidPresignedSignatureAsync(provider, data, signerAddress);
+ }
-/**
- * Verifies that the provided presigned signature is valid according to the 0x Protocol smart contracts
- * @param data The hex encoded data signed by the supplied signature.
- * @param signature A hex encoded presigned 0x Protocol signature made up of: [SignatureType.Presigned]
- * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
- * @return Whether the data was preSigned by the supplied signerAddress.
- */
-export async function isValidPresignedSignatureAsync(
- provider: Provider,
- data: string,
- signerAddress: string,
-): Promise<boolean> {
- assert.isWeb3Provider('provider', provider);
- assert.isHexString('data', data);
- assert.isETHAddressHex('signerAddress', signerAddress);
- const exchangeContract = new ExchangeContract(artifacts.Exchange.compilerOutput.abi, signerAddress, provider);
- const isValid = await exchangeContract.preSigned.callAsync(data, signerAddress);
- return isValid;
-}
-
-/**
- * Verifies that the provided wallet signature is valid according to the 0x Protocol smart contracts
- * @param data The hex encoded data signed by the supplied signature.
- * @param signature A hex encoded presigned 0x Protocol signature made up of: [SignatureType.Presigned]
- * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
- * @return Whether the data was preSigned by the supplied signerAddress.
- */
-export async function isValidWalletSignatureAsync(
- provider: Provider,
- data: string,
- signature: string,
- signerAddress: string,
-): Promise<boolean> {
- assert.isWeb3Provider('provider', provider);
- assert.isHexString('data', data);
- assert.isHexString('signature', signature);
- assert.isETHAddressHex('signerAddress', signerAddress);
- // tslint:disable-next-line:custom-no-magic-numbers
- const signatureWithoutType = signature.slice(-2);
- const walletContract = new IWalletContract(artifacts.IWallet.compilerOutput.abi, signerAddress, provider);
- const isValid = await walletContract.isValidSignature.callAsync(data, signatureWithoutType);
- return isValid;
-}
-
-/**
- * Verifies that the provided validator signature is valid according to the 0x Protocol smart contracts
- * @param data The hex encoded data signed by the supplied signature.
- * @param signature A hex encoded presigned 0x Protocol signature made up of: [SignatureType.Presigned]
- * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
- * @return Whether the data was preSigned by the supplied signerAddress.
- */
-export async function isValidValidatorSignatureAsync(
- provider: Provider,
- data: string,
- signature: string,
- signerAddress: string,
-): Promise<boolean> {
- assert.isWeb3Provider('provider', provider);
- assert.isHexString('data', data);
- assert.isHexString('signature', signature);
- assert.isETHAddressHex('signerAddress', signerAddress);
- const validatorSignature = parseValidatorSignature(signature);
- const exchangeContract = new ExchangeContract(artifacts.Exchange.compilerOutput.abi, signerAddress, provider);
- const isValidatorApproved = await exchangeContract.allowedValidators.callAsync(
- signerAddress,
- validatorSignature.validatorAddress,
- );
- if (!isValidatorApproved) {
- throw new Error(`Validator ${validatorSignature.validatorAddress} was not pre-approved by ${signerAddress}.`);
- }
+ case SignatureType.Trezor: {
+ const prefixedMessageHex = signatureUtils.addSignedMessagePrefix(data, SignerType.Trezor);
+ const ecSignature = signatureUtils.parseECSignature(signature);
+ return signatureUtils.isValidECSignature(prefixedMessageHex, ecSignature, signerAddress);
+ }
- const validatorContract = new IValidatorContract(artifacts.IValidator.compilerOutput.abi, signerAddress, provider);
- const isValid = await validatorContract.isValidSignature.callAsync(
- data,
- signerAddress,
- validatorSignature.signature,
- );
- return isValid;
-}
-
-/**
- * Checks if the supplied elliptic curve signature corresponds to signing `data` with
- * the private key corresponding to `signerAddress`
- * @param data The hex encoded data signed by the supplied signature.
- * @param signature An object containing the elliptic curve signature parameters.
- * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
- * @return Whether the ECSignature is valid.
- */
-export function isValidECSignature(data: string, signature: ECSignature, signerAddress: string): boolean {
- assert.isHexString('data', data);
- assert.doesConformToSchema('signature', signature, schemas.ecSignatureSchema);
- assert.isETHAddressHex('signerAddress', signerAddress);
-
- const msgHashBuff = ethUtil.toBuffer(data);
- try {
- const pubKey = ethUtil.ecrecover(
- msgHashBuff,
- signature.v,
- ethUtil.toBuffer(signature.r),
- ethUtil.toBuffer(signature.s),
+ default:
+ throw new Error(`Unhandled SignatureType: ${signatureTypeIndexIfExists}`);
+ }
+ },
+ /**
+ * Verifies that the provided presigned signature is valid according to the 0x Protocol smart contracts
+ * @param provider Web3 provider to use for all JSON RPC requests
+ * @param data The hex encoded data signed by the supplied signature
+ * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
+ * @return Whether the data was preSigned by the supplied signerAddress
+ */
+ async isValidPresignedSignatureAsync(provider: Provider, data: string, signerAddress: string): Promise<boolean> {
+ assert.isWeb3Provider('provider', provider);
+ assert.isHexString('data', data);
+ assert.isETHAddressHex('signerAddress', signerAddress);
+ const exchangeContract = new ExchangeContract(artifacts.Exchange.compilerOutput.abi, signerAddress, provider);
+ const isValid = await exchangeContract.preSigned.callAsync(data, signerAddress);
+ return isValid;
+ },
+ /**
+ * Verifies that the provided wallet signature is valid according to the 0x Protocol smart contracts
+ * @param provider Web3 provider to use for all JSON RPC requests
+ * @param data The hex encoded data signed by the supplied signature.
+ * @param signature A hex encoded presigned 0x Protocol signature made up of: [SignatureType.Presigned]
+ * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
+ * @return Whether the data was preSigned by the supplied signerAddress.
+ */
+ async isValidWalletSignatureAsync(
+ provider: Provider,
+ data: string,
+ signature: string,
+ signerAddress: string,
+ ): Promise<boolean> {
+ assert.isWeb3Provider('provider', provider);
+ assert.isHexString('data', data);
+ assert.isHexString('signature', signature);
+ assert.isETHAddressHex('signerAddress', signerAddress);
+ // tslint:disable-next-line:custom-no-magic-numbers
+ const signatureWithoutType = signature.slice(-2);
+ const walletContract = new IWalletContract(artifacts.IWallet.compilerOutput.abi, signerAddress, provider);
+ const isValid = await walletContract.isValidSignature.callAsync(data, signatureWithoutType);
+ return isValid;
+ },
+ /**
+ * Verifies that the provided validator signature is valid according to the 0x Protocol smart contracts
+ * @param provider Web3 provider to use for all JSON RPC requests
+ * @param data The hex encoded data signed by the supplied signature.
+ * @param signature A hex encoded presigned 0x Protocol signature made up of: [SignatureType.Presigned]
+ * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
+ * @return Whether the data was preSigned by the supplied signerAddress.
+ */
+ async isValidValidatorSignatureAsync(
+ provider: Provider,
+ data: string,
+ signature: string,
+ signerAddress: string,
+ ): Promise<boolean> {
+ assert.isWeb3Provider('provider', provider);
+ assert.isHexString('data', data);
+ assert.isHexString('signature', signature);
+ assert.isETHAddressHex('signerAddress', signerAddress);
+ const validatorSignature = parseValidatorSignature(signature);
+ const exchangeContract = new ExchangeContract(artifacts.Exchange.compilerOutput.abi, signerAddress, provider);
+ const isValidatorApproved = await exchangeContract.allowedValidators.callAsync(
+ signerAddress,
+ validatorSignature.validatorAddress,
);
- const retrievedAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey));
- return retrievedAddress === signerAddress;
- } catch (err) {
- return false;
- }
-}
-
-/**
- * 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
- * @param orderHash Hex encoded orderHash 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.
- * @param signerType Different signers add/require different prefixes to be prepended to the message being signed.
- * Since we cannot know ahead of time which signer you are using, you must supply a SignerType.
- * @return A hex encoded string containing the Elliptic curve signature generated by signing the orderHash and the Signature Type.
- */
-export async function ecSignOrderHashAsync(
- provider: Provider,
- orderHash: string,
- signerAddress: string,
- signerType: SignerType,
-): Promise<string> {
- assert.isWeb3Provider('provider', provider);
- assert.isHexString('orderHash', orderHash);
- assert.isETHAddressHex('signerAddress', signerAddress);
- const web3Wrapper = new Web3Wrapper(provider);
- await assert.isSenderAddressAsync('signerAddress', signerAddress, web3Wrapper);
- const normalizedSignerAddress = signerAddress.toLowerCase();
+ if (!isValidatorApproved) {
+ throw new Error(
+ `Validator ${validatorSignature.validatorAddress} was not pre-approved by ${signerAddress}.`,
+ );
+ }
- let msgHashHex = orderHash;
- const prefixedMsgHashHex = addSignedMessagePrefix(orderHash, signerType);
- // Metamask incorrectly implements eth_sign and does not prefix the message as per the spec
- // Source: https://github.com/MetaMask/metamask-extension/commit/a9d36860bec424dcee8db043d3e7da6a5ff5672e
- if (signerType === SignerType.Metamask) {
- msgHashHex = prefixedMsgHashHex;
- }
- const signature = await web3Wrapper.signMessageAsync(normalizedSignerAddress, msgHashHex);
+ const validatorContract = new IValidatorContract(
+ artifacts.IValidator.compilerOutput.abi,
+ signerAddress,
+ provider,
+ );
+ const isValid = await validatorContract.isValidSignature.callAsync(
+ data,
+ signerAddress,
+ validatorSignature.signature,
+ );
+ return isValid;
+ },
+ /**
+ * Checks if the supplied elliptic curve signature corresponds to signing `data` with
+ * the private key corresponding to `signerAddress`
+ * @param data The hex encoded data signed by the supplied signature.
+ * @param signature An object containing the elliptic curve signature parameters.
+ * @param signerAddress The hex encoded address that signed the data, producing the supplied signature.
+ * @return Whether the ECSignature is valid.
+ */
+ isValidECSignature(data: string, signature: ECSignature, signerAddress: string): boolean {
+ assert.isHexString('data', data);
+ assert.doesConformToSchema('signature', signature, schemas.ecSignatureSchema);
+ assert.isETHAddressHex('signerAddress', signerAddress);
- // HACK: There is no consensus on whether the signatureHex string should be formatted as
- // v + r + s OR r + s + v, and different clients (even different versions of the same client)
- // return the signature params in different orders. In order to support all client implementations,
- // we parse the signature in both ways, and evaluate if either one is a valid signature.
- // r + s + v is the most prevalent format from eth_sign, so we attempt this first.
- // tslint:disable-next-line:custom-no-magic-numbers
- const validVParamValues = [27, 28];
- const ecSignatureRSV = parseSignatureHexAsRSV(signature);
- if (_.includes(validVParamValues, ecSignatureRSV.v)) {
- const isValidRSVSignature = isValidECSignature(prefixedMsgHashHex, ecSignatureRSV, normalizedSignerAddress);
- if (isValidRSVSignature) {
- const convertedSignatureHex = convertECSignatureToSignatureHex(ecSignatureRSV, signerType);
- return convertedSignatureHex;
+ const msgHashBuff = ethUtil.toBuffer(data);
+ try {
+ const pubKey = ethUtil.ecrecover(
+ msgHashBuff,
+ signature.v,
+ ethUtil.toBuffer(signature.r),
+ ethUtil.toBuffer(signature.s),
+ );
+ const retrievedAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(pubKey));
+ return retrievedAddress === signerAddress;
+ } catch (err) {
+ return false;
}
- }
- const ecSignatureVRS = parseSignatureHexAsVRS(signature);
- if (_.includes(validVParamValues, ecSignatureVRS.v)) {
- const isValidVRSSignature = isValidECSignature(prefixedMsgHashHex, ecSignatureVRS, normalizedSignerAddress);
- if (isValidVRSSignature) {
- const convertedSignatureHex = convertECSignatureToSignatureHex(ecSignatureVRS, signerType);
- return convertedSignatureHex;
+ },
+ /**
+ * 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
+ * @param orderHash Hex encoded orderHash 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.
+ * @param signerType Different signers add/require different prefixes to be prepended to the message being signed.
+ * Since we cannot know ahead of time which signer you are using, you must supply a SignerType.
+ * @return A hex encoded string containing the Elliptic curve signature generated by signing the orderHash and the Signature Type.
+ */
+ async ecSignOrderHashAsync(
+ provider: Provider,
+ orderHash: string,
+ signerAddress: string,
+ signerType: SignerType,
+ ): Promise<string> {
+ assert.isWeb3Provider('provider', provider);
+ assert.isHexString('orderHash', orderHash);
+ assert.isETHAddressHex('signerAddress', signerAddress);
+ const web3Wrapper = new Web3Wrapper(provider);
+ await assert.isSenderAddressAsync('signerAddress', signerAddress, web3Wrapper);
+ const normalizedSignerAddress = signerAddress.toLowerCase();
+
+ let msgHashHex = orderHash;
+ const prefixedMsgHashHex = signatureUtils.addSignedMessagePrefix(orderHash, signerType);
+ // Metamask incorrectly implements eth_sign and does not prefix the message as per the spec
+ // Source: https://github.com/MetaMask/metamask-extension/commit/a9d36860bec424dcee8db043d3e7da6a5ff5672e
+ if (signerType === SignerType.Metamask) {
+ msgHashHex = prefixedMsgHashHex;
}
- }
+ const signature = await web3Wrapper.signMessageAsync(normalizedSignerAddress, msgHashHex);
- throw new Error(OrderError.InvalidSignature);
-}
-/**
- * Combines ECSignature with V,R,S and the relevant signature type for use in 0x protocol
- * @param ecSignature The ECSignature of the signed data
- * @param signerType The SignerType of the signed data
- * @return Hex encoded string of signature (v,r,s) with Signature Type
- */
-export function convertECSignatureToSignatureHex(ecSignature: ECSignature, signerType: SignerType): string {
- const signatureBuffer = Buffer.concat([
- ethUtil.toBuffer(ecSignature.v),
- ethUtil.toBuffer(ecSignature.r),
- ethUtil.toBuffer(ecSignature.s),
- ]);
- const signatureHex = `0x${signatureBuffer.toString('hex')}`;
- let signatureType;
- switch (signerType) {
- case SignerType.Metamask:
- case SignerType.Ledger:
- case SignerType.Default: {
- signatureType = SignatureType.EthSign;
- break;
+ // HACK: There is no consensus on whether the signatureHex string should be formatted as
+ // v + r + s OR r + s + v, and different clients (even different versions of the same client)
+ // return the signature params in different orders. In order to support all client implementations,
+ // we parse the signature in both ways, and evaluate if either one is a valid signature.
+ // r + s + v is the most prevalent format from eth_sign, so we attempt this first.
+ // tslint:disable-next-line:custom-no-magic-numbers
+ const validVParamValues = [27, 28];
+ const ecSignatureRSV = parseSignatureHexAsRSV(signature);
+ if (_.includes(validVParamValues, ecSignatureRSV.v)) {
+ const isValidRSVSignature = signatureUtils.isValidECSignature(
+ prefixedMsgHashHex,
+ ecSignatureRSV,
+ normalizedSignerAddress,
+ );
+ if (isValidRSVSignature) {
+ const convertedSignatureHex = signatureUtils.convertECSignatureToSignatureHex(
+ ecSignatureRSV,
+ signerType,
+ );
+ return convertedSignatureHex;
+ }
}
- case SignerType.Trezor: {
- signatureType = SignatureType.Trezor;
- break;
+ const ecSignatureVRS = parseSignatureHexAsVRS(signature);
+ if (_.includes(validVParamValues, ecSignatureVRS.v)) {
+ const isValidVRSSignature = signatureUtils.isValidECSignature(
+ prefixedMsgHashHex,
+ ecSignatureVRS,
+ normalizedSignerAddress,
+ );
+ if (isValidVRSSignature) {
+ const convertedSignatureHex = signatureUtils.convertECSignatureToSignatureHex(
+ ecSignatureVRS,
+ signerType,
+ );
+ return convertedSignatureHex;
+ }
}
- default:
- throw new Error(`Unrecognized SignerType: ${signerType}`);
- }
- const signatureWithType = convertToSignatureWithType(signatureHex, signatureType);
- return signatureWithType;
-}
-/**
- * Combines the signature proof and the Signature Type.
- * @param signature The hex encoded signature proof
- * @param signatureType The signature type, i.e EthSign, Trezor, Wallet etc.
- * @return Hex encoded string of signature proof with Signature Type
- */
-export function convertToSignatureWithType(signature: string, signatureType: SignatureType): string {
- const signatureBuffer = Buffer.concat([ethUtil.toBuffer(signature), ethUtil.toBuffer(signatureType)]);
- const signatureHex = `0x${signatureBuffer.toString('hex')}`;
- return signatureHex;
-}
-/**
- * Adds the relevant prefix to the message being signed.
- * @param message Message to sign
- * @param signerType The type of message prefix to add for a given SignerType. Different signers expect
- * specific message prefixes.
- * @return Prefixed message
- */
-export function addSignedMessagePrefix(message: string, signerType: SignerType = SignerType.Default): string {
- assert.isString('message', message);
- assert.doesBelongToStringEnum('signerType', signerType, SignerType);
- switch (signerType) {
- case SignerType.Metamask:
- case SignerType.Ledger:
- case SignerType.Default: {
- const msgBuff = ethUtil.toBuffer(message);
- const prefixedMsgBuff = ethUtil.hashPersonalMessage(msgBuff);
- const prefixedMsgHex = ethUtil.bufferToHex(prefixedMsgBuff);
- return prefixedMsgHex;
+
+ throw new Error(OrderError.InvalidSignature);
+ },
+ /**
+ * Combines ECSignature with V,R,S and the relevant signature type for use in 0x protocol
+ * @param ecSignature The ECSignature of the signed data
+ * @param signerType The SignerType of the signed data
+ * @return Hex encoded string of signature (v,r,s) with Signature Type
+ */
+ convertECSignatureToSignatureHex(ecSignature: ECSignature, signerType: SignerType): string {
+ const signatureBuffer = Buffer.concat([
+ ethUtil.toBuffer(ecSignature.v),
+ ethUtil.toBuffer(ecSignature.r),
+ ethUtil.toBuffer(ecSignature.s),
+ ]);
+ const signatureHex = `0x${signatureBuffer.toString('hex')}`;
+ let signatureType;
+ switch (signerType) {
+ case SignerType.Metamask:
+ case SignerType.Ledger:
+ case SignerType.Default: {
+ signatureType = SignatureType.EthSign;
+ break;
+ }
+ case SignerType.Trezor: {
+ signatureType = SignatureType.Trezor;
+ break;
+ }
+ default:
+ throw new Error(`Unrecognized SignerType: ${signerType}`);
}
- case SignerType.Trezor: {
- const msgBuff = ethUtil.toBuffer(message);
- const prefixedMsgBuff = hashTrezorPersonalMessage(msgBuff);
- const prefixedMsgHex = ethUtil.bufferToHex(prefixedMsgBuff);
- return prefixedMsgHex;
+ const signatureWithType = signatureUtils.convertToSignatureWithType(signatureHex, signatureType);
+ return signatureWithType;
+ },
+ /**
+ * Combines the signature proof and the Signature Type.
+ * @param signature The hex encoded signature proof
+ * @param signatureType The signature type, i.e EthSign, Trezor, Wallet etc.
+ * @return Hex encoded string of signature proof with Signature Type
+ */
+ convertToSignatureWithType(signature: string, signatureType: SignatureType): string {
+ const signatureBuffer = Buffer.concat([ethUtil.toBuffer(signature), ethUtil.toBuffer(signatureType)]);
+ const signatureHex = `0x${signatureBuffer.toString('hex')}`;
+ return signatureHex;
+ },
+ /**
+ * Adds the relevant prefix to the message being signed.
+ * @param message Message to sign
+ * @param signerType The type of message prefix to add for a given SignerType. Different signers expect
+ * specific message prefixes.
+ * @return Prefixed message
+ */
+ addSignedMessagePrefix(message: string, signerType: SignerType = SignerType.Default): string {
+ assert.isString('message', message);
+ assert.doesBelongToStringEnum('signerType', signerType, SignerType);
+ switch (signerType) {
+ case SignerType.Metamask:
+ case SignerType.Ledger:
+ case SignerType.Default: {
+ const msgBuff = ethUtil.toBuffer(message);
+ const prefixedMsgBuff = ethUtil.hashPersonalMessage(msgBuff);
+ const prefixedMsgHex = ethUtil.bufferToHex(prefixedMsgBuff);
+ return prefixedMsgHex;
+ }
+ case SignerType.Trezor: {
+ const msgBuff = ethUtil.toBuffer(message);
+ const prefixedMsgBuff = hashTrezorPersonalMessage(msgBuff);
+ const prefixedMsgHex = ethUtil.bufferToHex(prefixedMsgBuff);
+ return prefixedMsgHex;
+ }
+ default:
+ throw new Error(`Unrecognized SignerType: ${signerType}`);
}
- default:
- throw new Error(`Unrecognized SignerType: ${signerType}`);
- }
-}
-
-/**
- * Parse a 0x protocol hex-encoded signature string into it's ECSignature components
- * @param signature A hex encoded ecSignature 0x Protocol signature
- * @return An ECSignature object with r,s,v parameters
- */
-export function parseECSignature(signature: string): ECSignature {
- assert.isHexString('signature', signature);
- const ecSignatureTypes = [SignatureType.EthSign, SignatureType.EIP712, SignatureType.Trezor];
- assert.isOneOfExpectedSignatureTypes(signature, ecSignatureTypes);
+ },
+ /**
+ * Parse a 0x protocol hex-encoded signature string into it's ECSignature components
+ * @param signature A hex encoded ecSignature 0x Protocol signature
+ * @return An ECSignature object with r,s,v parameters
+ */
+ parseECSignature(signature: string): ECSignature {
+ assert.isHexString('signature', signature);
+ const ecSignatureTypes = [SignatureType.EthSign, SignatureType.EIP712, SignatureType.Trezor];
+ assert.isOneOfExpectedSignatureTypes(signature, ecSignatureTypes);
- // tslint:disable-next-line:custom-no-magic-numbers
- const vrsHex = signature.slice(0, -2);
- const ecSignature = parseSignatureHexAsVRS(vrsHex);
+ // tslint:disable-next-line:custom-no-magic-numbers
+ const vrsHex = signature.slice(0, -2);
+ const ecSignature = parseSignatureHexAsVRS(vrsHex);
- return ecSignature;
-}
+ return ecSignature;
+ },
+};
function hashTrezorPersonalMessage(message: Buffer): Buffer {
const prefix = ethUtil.toBuffer('\x19Ethereum Signed Message:\n' + String.fromCharCode(message.byteLength));