From 9e8031d5e3cf94cabe07685be510397367e90413 Mon Sep 17 00:00:00 2001 From: Jacob Evans Date: Tue, 9 Oct 2018 18:26:13 +1100 Subject: Throw and handle errors from Providers. In web3 wrapper when a response contains an error field we throw this rather than return response.result which is often undefined. In Signature Utils we handle the error thrown when a user rejects the signing dialogue to prevent double signing. Exposed the ZeroExTransaction JSON schema. In Website only use the MetamaskSubprovider if we can detect the provider is Metamask --- packages/order-utils/src/signature_utils.ts | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (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 e518b29a0..2605ccd32 100644 --- a/packages/order-utils/src/signature_utils.ts +++ b/packages/order-utils/src/signature_utils.ts @@ -194,7 +194,7 @@ export const signatureUtils = { } }, /** - * Signs an order and returns its elliptic curve signature and signature type. First `eth_signTypedData` is requested + * Signs an order and returns a SignedOrder. First `eth_signTypedData` is requested * then a fallback to `eth_sign` if not available on the supplied provider. * @param order The Order to sign. * @param signerAddress The hex encoded Ethereum address you wish to sign it with. This address @@ -202,11 +202,18 @@ export const signatureUtils = { * @return A SignedOrder containing the order and Elliptic curve signature with Signature Type. */ async ecSignOrderAsync(provider: Provider, order: Order, signerAddress: string): Promise { + assert.doesConformToSchema('order', order, schemas.orderSchema, [schemas.hexSchema]); try { - const signedOrder = signatureUtils.ecSignTypedDataOrderAsync(provider, order, signerAddress); + const signedOrder = await signatureUtils.ecSignTypedDataOrderAsync(provider, order, signerAddress); return signedOrder; } catch (err) { - // Fallback to using EthSign when ethSignTypedData is not supported + // HACK: We are unable to handle specific errors thrown since provider is not an object + // under our control. It could be Metamask Web3, Ethers, or any general RPC provider. + // We check for a user denying the signature request in a way that supports Metamask and + // Coinbase Wallet + if (err.message.includes('User denied message signature')) { + throw err; + } const orderHash = orderHashUtils.getOrderHashHex(order); const signatureHex = await signatureUtils.ecSignHashAsync(provider, orderHash, signerAddress); const signedOrder = { @@ -217,7 +224,7 @@ export const signatureUtils = { } }, /** - * Signs an order using `eth_signTypedData` and returns its elliptic curve signature and signature type. + * Signs an order using `eth_signTypedData` and returns a SignedOrder. * @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 supplied Provider. @@ -226,6 +233,7 @@ export const signatureUtils = { async ecSignTypedDataOrderAsync(provider: Provider, order: Order, signerAddress: string): Promise { assert.isWeb3Provider('provider', provider); assert.isETHAddressHex('signerAddress', signerAddress); + assert.doesConformToSchema('order', order, schemas.orderSchema, [schemas.hexSchema]); const web3Wrapper = new Web3Wrapper(provider); await assert.isSenderAddressAsync('signerAddress', signerAddress, web3Wrapper); const normalizedSignerAddress = signerAddress.toLowerCase(); @@ -247,14 +255,16 @@ export const signatureUtils = { } catch (err) { // Detect if Metamask to transition users to the MetamaskSubprovider if ((provider as any).isMetaMask) { - throw new Error(`Unsupported Provider, please use MetamaskSubprovider: ${err.message}`); + throw new Error( + `MetaMask provider must be wrapped in a MetamaskSubprovider (from the '@0xproject/subproviders' package) in order to work with this method.`, + ); } else { throw err; } } }, /** - * Signs a hash and returns its elliptic curve signature and signature type. + * Signs a hash using `eth_sign` and returns its elliptic curve signature and signature type. * @param msgHash Hex encoded message to sign. * @param signerAddress The hex encoded Ethereum address you wish to sign it with. This address * must be available via the supplied Provider. @@ -303,7 +313,9 @@ export const signatureUtils = { } // Detect if Metamask to transition users to the MetamaskSubprovider if ((provider as any).isMetaMask) { - throw new Error('Unsupported Provider, please use MetamaskSubprovider.'); + throw new Error( + `MetaMask provider must be wrapped in a MetamaskSubprovider (from the '@0xproject/subproviders' package) in order to work with this method.`, + ); } else { throw new Error(OrderError.InvalidSignature); } -- cgit v1.2.3