diff options
author | Jacob Evans <jacob@dekz.net> | 2018-10-09 15:26:13 +0800 |
---|---|---|
committer | Jacob Evans <jacob@dekz.net> | 2018-10-09 16:01:36 +0800 |
commit | 9e8031d5e3cf94cabe07685be510397367e90413 (patch) | |
tree | 548a3918ed9eb5325db3973d76924907b142aae0 /packages/order-utils/src | |
parent | e1236a484623e9d2caab823c476175cb255ae816 (diff) | |
download | dexon-sol-tools-9e8031d5e3cf94cabe07685be510397367e90413.tar dexon-sol-tools-9e8031d5e3cf94cabe07685be510397367e90413.tar.gz dexon-sol-tools-9e8031d5e3cf94cabe07685be510397367e90413.tar.bz2 dexon-sol-tools-9e8031d5e3cf94cabe07685be510397367e90413.tar.lz dexon-sol-tools-9e8031d5e3cf94cabe07685be510397367e90413.tar.xz dexon-sol-tools-9e8031d5e3cf94cabe07685be510397367e90413.tar.zst dexon-sol-tools-9e8031d5e3cf94cabe07685be510397367e90413.zip |
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
Diffstat (limited to 'packages/order-utils/src')
-rw-r--r-- | packages/order-utils/src/eip712_utils.ts | 8 | ||||
-rw-r--r-- | packages/order-utils/src/order_hash.ts | 2 | ||||
-rw-r--r-- | packages/order-utils/src/signature_utils.ts | 26 |
3 files changed, 28 insertions, 8 deletions
diff --git a/packages/order-utils/src/eip712_utils.ts b/packages/order-utils/src/eip712_utils.ts index 43b421de7..56f736500 100644 --- a/packages/order-utils/src/eip712_utils.ts +++ b/packages/order-utils/src/eip712_utils.ts @@ -1,3 +1,5 @@ +import { assert } from '@0xproject/assert'; +import { schemas } from '@0xproject/json-schemas'; import { EIP712Object, EIP712TypedData, EIP712Types, Order, ZeroExTransaction } from '@0xproject/types'; import * as _ from 'lodash'; @@ -18,6 +20,8 @@ export const eip712Utils = { message: EIP712Object, exchangeAddress: string, ): EIP712TypedData => { + assert.isETHAddressHex('exchangeAddress', exchangeAddress); + assert.isString('primaryType', primaryType); const typedData = { types: { EIP712Domain: constants.EIP712_DOMAIN_SCHEMA.parameters, @@ -31,6 +35,7 @@ export const eip712Utils = { message, primaryType, }; + assert.doesConformToSchema('typedData', typedData, schemas.eip712TypedDataSchema); return typedData; }, /** @@ -39,6 +44,7 @@ export const eip712Utils = { * @return A typed data object */ createOrderTypedData: (order: Order): EIP712TypedData => { + assert.doesConformToSchema('order', order, schemas.orderSchema, [schemas.hexSchema]); const normalizedOrder = _.mapValues(order, value => { return !_.isString(value) ? value.toString() : value; }); @@ -61,6 +67,8 @@ export const eip712Utils = { zeroExTransaction: ZeroExTransaction, exchangeAddress: string, ): EIP712TypedData => { + assert.isETHAddressHex('exchangeAddress', exchangeAddress); + assert.doesConformToSchema('zeroExTransaction', zeroExTransaction, schemas.zeroExTransactionSchema); const normalizedTransaction = _.mapValues(zeroExTransaction, value => { return !_.isString(value) ? value.toString() : value; }); diff --git a/packages/order-utils/src/order_hash.ts b/packages/order-utils/src/order_hash.ts index a6dd6688c..b523a3523 100644 --- a/packages/order-utils/src/order_hash.ts +++ b/packages/order-utils/src/order_hash.ts @@ -52,7 +52,7 @@ export const orderHashUtils = { */ getOrderHashBuffer(order: SignedOrder | Order): Buffer { const typedData = eip712Utils.createOrderTypedData(order); - const orderHashBuff = signTypedDataUtils.signTypedDataHash(typedData); + const orderHashBuff = signTypedDataUtils.generateTypedDataHash(typedData); return orderHashBuff; }, }; 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<SignedOrder> { + 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<SignedOrder> { 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); } |