diff options
author | Jacob Evans <jacob@dekz.net> | 2018-10-05 09:45:53 +0800 |
---|---|---|
committer | Jacob Evans <jacob@dekz.net> | 2018-10-05 15:12:17 +0800 |
commit | 75d274f330dc0c18577e764ca77ffb36d5a3f27e (patch) | |
tree | 9a70714a89783dfe58ffa002d39f3967de957bdc /packages/subproviders | |
parent | 6e462b7dba61611a5347c9aa181d4ae69294d7af (diff) | |
download | dexon-sol-tools-75d274f330dc0c18577e764ca77ffb36d5a3f27e.tar dexon-sol-tools-75d274f330dc0c18577e764ca77ffb36d5a3f27e.tar.gz dexon-sol-tools-75d274f330dc0c18577e764ca77ffb36d5a3f27e.tar.bz2 dexon-sol-tools-75d274f330dc0c18577e764ca77ffb36d5a3f27e.tar.lz dexon-sol-tools-75d274f330dc0c18577e764ca77ffb36d5a3f27e.tar.xz dexon-sol-tools-75d274f330dc0c18577e764ca77ffb36d5a3f27e.tar.zst dexon-sol-tools-75d274f330dc0c18577e764ca77ffb36d5a3f27e.zip |
Return SignedOrder from signing utils.
Create a helper back in EIP712Utils for code cleanup.
Moved constants in order-utils into the constants object
Diffstat (limited to 'packages/subproviders')
8 files changed, 65 insertions, 32 deletions
diff --git a/packages/subproviders/CHANGELOG.json b/packages/subproviders/CHANGELOG.json index 6a6f7848b..387207b01 100644 --- a/packages/subproviders/CHANGELOG.json +++ b/packages/subproviders/CHANGELOG.json @@ -3,11 +3,11 @@ "version": "2.1.0", "changes": [ { - "note": "Add Metamask Subprovider to handle inconsistent JSON RPC behaviour", + "note": "Add `MetamaskSubprovider` to handle inconsistent JSON RPC behaviour", "pr": 1102 }, { - "note": "Add support for eth_signTypedData in Mnemonic, Private and EthLightWallet", + "note": "Add support for `eth_signTypedData` in wallets Mnemonic, Private and EthLightWallet", "pr": 1102 } ] diff --git a/packages/subproviders/src/index.ts b/packages/subproviders/src/index.ts index 8b5446007..6a8100e68 100644 --- a/packages/subproviders/src/index.ts +++ b/packages/subproviders/src/index.ts @@ -48,6 +48,13 @@ export { LedgerGetAddressResult, } from './types'; -export { ECSignature } from '@0xproject/types'; +export { + ECSignature, + EIP712Object, + EIP712ObjectValue, + EIP712TypedData, + EIP712Types, + EIP712Parameter, +} from '@0xproject/types'; export { JSONRPCRequestPayload, Provider, JSONRPCResponsePayload, JSONRPCErrorCallback } from 'ethereum-types'; diff --git a/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts index e3afeff1b..a1d93ac49 100644 --- a/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts +++ b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts @@ -1,3 +1,4 @@ +import { EIP712TypedData } from '@0xproject/types'; import * as lightwallet from 'eth-lightwallet'; import { PartialTxParams } from '../types'; @@ -48,16 +49,16 @@ export class EthLightwalletSubprovider extends BaseWalletSubprovider { // Lightwallet loses the chain id information when hex encoding the transaction // this results in a different signature on certain networks. PrivateKeyWallet // respects this as it uses the parameters passed in - let privKey = this._keystore.exportPrivateKey(txParams.from, this._pwDerivedKey); - const privKeyWallet = new PrivateKeyWalletSubprovider(privKey); - privKey = ''; - const privKeySignature = await privKeyWallet.signTransactionAsync(txParams); - return privKeySignature; + let privateKey = this._keystore.exportPrivateKey(txParams.from, this._pwDerivedKey); + const privateKeyWallet = new PrivateKeyWalletSubprovider(privateKey); + privateKey = ''; + const privateKeySignature = await privateKeyWallet.signTransactionAsync(txParams); + return privateKeySignature; } /** * Sign a personal Ethereum signed message. The signing account will be the account * associated with the provided address. - * If you've added the this Subprovider to your app's provider, you can simply send an `eth_sign` + * If you've added this Subprovider to your app's provider, you can simply send an `eth_sign` * or `personal_sign` JSON RPC request, and this method will be called auto-magically. * If you are not using this via a ProviderEngine instance, you can call it directly. * @param data Hex string message to sign @@ -65,10 +66,10 @@ export class EthLightwalletSubprovider extends BaseWalletSubprovider { * @return Signature hex string (order: rsv) */ public async signPersonalMessageAsync(data: string, address: string): Promise<string> { - let privKey = this._keystore.exportPrivateKey(address, this._pwDerivedKey); - const privKeyWallet = new PrivateKeyWalletSubprovider(privKey); - privKey = ''; - const result = privKeyWallet.signPersonalMessageAsync(data, address); + let privateKey = this._keystore.exportPrivateKey(address, this._pwDerivedKey); + const privateKeyWallet = new PrivateKeyWalletSubprovider(privateKey); + privateKey = ''; + const result = privateKeyWallet.signPersonalMessageAsync(data, address); return result; } /** @@ -80,11 +81,11 @@ export class EthLightwalletSubprovider extends BaseWalletSubprovider { * @param data the typed data object * @return Signature hex string (order: rsv) */ - public async signTypedDataAsync(address: string, typedData: any): Promise<string> { - let privKey = this._keystore.exportPrivateKey(address, this._pwDerivedKey); - const privKeyWallet = new PrivateKeyWalletSubprovider(privKey); - privKey = ''; - const result = privKeyWallet.signTypedDataAsync(address, typedData); + public async signTypedDataAsync(address: string, typedData: EIP712TypedData): Promise<string> { + let privateKey = this._keystore.exportPrivateKey(address, this._pwDerivedKey); + const privateKeyWallet = new PrivateKeyWalletSubprovider(privateKey); + privateKey = ''; + const result = privateKeyWallet.signTypedDataAsync(address, typedData); return result; } } diff --git a/packages/subproviders/src/subproviders/metamask_subprovider.ts b/packages/subproviders/src/subproviders/metamask_subprovider.ts index 724edd574..46fc2a9cd 100644 --- a/packages/subproviders/src/subproviders/metamask_subprovider.ts +++ b/packages/subproviders/src/subproviders/metamask_subprovider.ts @@ -18,7 +18,7 @@ export class MetamaskSubprovider extends Subprovider { private readonly _web3Wrapper: Web3Wrapper; private readonly _provider: Provider; /** - * Instantiates a new SignerSubprovider + * Instantiates a new MetamaskSubprovider * @param provider Web3 provider that should handle all user account related requests */ constructor(provider: Provider) { @@ -83,7 +83,9 @@ export class MetamaskSubprovider extends Subprovider { case 'eth_signTypedData_v3': [address, message] = payload.params; try { - // Metamask has namespaced signTypedData to v3 for an indeterminate period of time. + // Metamask supports multiple versions and has namespaced signTypedData to v3 for an indeterminate period of time. + // eth_signTypedData is mapped to an older implementation before the spec was finalized. + // Source: https://github.com/MetaMask/metamask-extension/blob/c49d854b55b3efd34c7fd0414b76f7feaa2eec7c/app/scripts/metamask-controller.js#L1262 // and expects message to be serialised as JSON const messageJSON = JSON.stringify(message); const signature = await this._web3Wrapper.sendRawPayloadAsync<string>({ diff --git a/packages/subproviders/src/subproviders/mnemonic_wallet.ts b/packages/subproviders/src/subproviders/mnemonic_wallet.ts index de99b632a..04a11c7be 100644 --- a/packages/subproviders/src/subproviders/mnemonic_wallet.ts +++ b/packages/subproviders/src/subproviders/mnemonic_wallet.ts @@ -1,4 +1,5 @@ import { assert } from '@0xproject/assert'; +import { EIP712TypedData } from '@0xproject/types'; import { addressUtils } from '@0xproject/utils'; import * as bip39 from 'bip39'; import HDNode = require('hdkey'); @@ -90,10 +91,10 @@ export class MnemonicWalletSubprovider extends BaseWalletSubprovider { } /** * Sign a personal Ethereum signed message. The signing account will be the account - * associated with the provided address. - * If you've added the MnemonicWalletSubprovider to your app's provider, you can simply send an `eth_sign` - * or `personal_sign` JSON RPC request, and this method will be called auto-magically. - * If you are not using this via a ProviderEngine instance, you can call it directly. + * associated with the provided address. If you've added the MnemonicWalletSubprovider to + * your app's provider, you can simply send an `eth_sign` or `personal_sign` JSON RPC request, + * and this method will be called auto-magically. If you are not using this via a ProviderEngine + * instance, you can call it directly. * @param data Hex string message to sign * @param address Address of the account to sign with * @return Signature hex string (order: rsv) @@ -109,16 +110,16 @@ export class MnemonicWalletSubprovider extends BaseWalletSubprovider { return sig; } /** - * Sign an EIP712 Typed Data message. The signing account will be the account - * associated with the provided address. - * If you've added this MnemonicWalletSubprovider to your app's provider, you can simply send an `eth_signTypedData` - * JSON RPC request, and this method will be called auto-magically. - * If you are not using this via a ProviderEngine instance, you can call it directly. + * Sign an EIP712 Typed Data message. The signing account will be the account + * associated with the provided address. If you've added this MnemonicWalletSubprovider to + * your app's provider, you can simply send an `eth_signTypedData` JSON RPC request, and + * this method will be called auto-magically. If you are not using this via a ProviderEngine + * instance, you can call it directly. * @param address Address of the account to sign with * @param data the typed data object * @return Signature hex string (order: rsv) */ - public async signTypedDataAsync(address: string, typedData: any): Promise<string> { + public async signTypedDataAsync(address: string, typedData: EIP712TypedData): Promise<string> { if (_.isUndefined(typedData)) { throw new Error(WalletSubproviderErrors.DataMissingForSignPersonalMessage); } diff --git a/packages/subproviders/src/subproviders/private_key_wallet.ts b/packages/subproviders/src/subproviders/private_key_wallet.ts index 51409077d..96e4190ed 100644 --- a/packages/subproviders/src/subproviders/private_key_wallet.ts +++ b/packages/subproviders/src/subproviders/private_key_wallet.ts @@ -1,4 +1,5 @@ import { assert } from '@0xproject/assert'; +import { EIP712TypedData } from '@0xproject/types'; import { signTypedDataUtils } from '@0xproject/utils'; import EthereumTx = require('ethereumjs-tx'); import * as ethUtil from 'ethereumjs-util'; @@ -95,7 +96,7 @@ export class PrivateKeyWalletSubprovider extends BaseWalletSubprovider { * @param data the typed data object * @return Signature hex string (order: rsv) */ - public async signTypedDataAsync(address: string, typedData: any): Promise<string> { + public async signTypedDataAsync(address: string, typedData: EIP712TypedData): Promise<string> { if (_.isUndefined(typedData)) { throw new Error(WalletSubproviderErrors.DataMissingForSignTypedData); } diff --git a/packages/subproviders/src/subproviders/signer.ts b/packages/subproviders/src/subproviders/signer.ts index 6b519865f..eda7db42e 100644 --- a/packages/subproviders/src/subproviders/signer.ts +++ b/packages/subproviders/src/subproviders/signer.ts @@ -14,7 +14,7 @@ import { Subprovider } from './subprovider'; export class SignerSubprovider extends Subprovider { private readonly _web3Wrapper: Web3Wrapper; /** - * Instantiates a new SignerSubprovider + * Instantiates a new SignerSubprovider. * @param provider Web3 provider that should handle all user account related requests */ constructor(provider: Provider) { diff --git a/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts b/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts index 063817a95..49698ce9e 100644 --- a/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts +++ b/packages/subproviders/test/unit/eth_lightwallet_subprovider_test.ts @@ -73,6 +73,13 @@ describe('EthLightwalletSubprovider', () => { const txHex = await ethLightwalletSubprovider.signTransactionAsync(fixtureData.TX_DATA); expect(txHex).to.be.equal(fixtureData.TX_DATA_SIGNED_RESULT); }); + it('signs an EIP712 sign typed data message', async () => { + const signature = await ethLightwalletSubprovider.signTypedDataAsync( + fixtureData.TEST_RPC_ACCOUNT_0, + fixtureData.EIP712_TEST_TYPED_DATA, + ); + expect(signature).to.be.equal(fixtureData.EIP712_TEST_TYPED_DATA_SIGNED_RESULT); + }); }); }); describe('calls through a provider', () => { @@ -129,6 +136,20 @@ describe('EthLightwalletSubprovider', () => { }); provider.sendAsync(payload, callback); }); + it('signs an EIP712 sign typed data message with eth_signTypedData', (done: DoneCallback) => { + const payload = { + jsonrpc: '2.0', + method: 'eth_signTypedData', + params: [fixtureData.TEST_RPC_ACCOUNT_0, fixtureData.EIP712_TEST_TYPED_DATA], + id: 1, + }; + const callback = reportCallbackErrors(done)((err: Error, response: JSONRPCResponsePayload) => { + expect(err).to.be.a('null'); + expect(response.result).to.be.equal(fixtureData.EIP712_TEST_TYPED_DATA_SIGNED_RESULT); + done(); + }); + provider.sendAsync(payload, callback); + }); }); describe('failure cases', () => { it('should throw if `data` param not hex when calling eth_sign', (done: DoneCallback) => { |