diff options
author | Cavan <cavan@radarrelay.com> | 2018-06-05 04:48:18 +0800 |
---|---|---|
committer | Fabio Berger <me@fabioberger.com> | 2018-06-26 01:39:23 +0800 |
commit | 7ce1e9b18d30cb76dd61f3859164cb09d091a3dd (patch) | |
tree | 02015f800591466b0c51f0349d223cd028dfb564 /packages/subproviders/src | |
parent | 1821f60fb5ddd4a36f34cce94acabba32b4236c6 (diff) | |
download | dexon-sol-tools-7ce1e9b18d30cb76dd61f3859164cb09d091a3dd.tar dexon-sol-tools-7ce1e9b18d30cb76dd61f3859164cb09d091a3dd.tar.gz dexon-sol-tools-7ce1e9b18d30cb76dd61f3859164cb09d091a3dd.tar.bz2 dexon-sol-tools-7ce1e9b18d30cb76dd61f3859164cb09d091a3dd.tar.lz dexon-sol-tools-7ce1e9b18d30cb76dd61f3859164cb09d091a3dd.tar.xz dexon-sol-tools-7ce1e9b18d30cb76dd61f3859164cb09d091a3dd.tar.zst dexon-sol-tools-7ce1e9b18d30cb76dd61f3859164cb09d091a3dd.zip |
Add eth-lightwallet subprovider and tests
Diffstat (limited to 'packages/subproviders/src')
-rw-r--r-- | packages/subproviders/src/globals.d.ts | 28 | ||||
-rw-r--r-- | packages/subproviders/src/index.ts | 2 | ||||
-rw-r--r-- | packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts | 88 |
3 files changed, 117 insertions, 1 deletions
diff --git a/packages/subproviders/src/globals.d.ts b/packages/subproviders/src/globals.d.ts index 4b3ecdf3c..1e104053f 100644 --- a/packages/subproviders/src/globals.d.ts +++ b/packages/subproviders/src/globals.d.ts @@ -16,6 +16,11 @@ interface ECSignature { r: string; s: string; } +interface ECSignatureBuffer { + v: number; + r: Buffer; + s: Buffer; +} interface LedgerTransport { close(): Promise<void>; @@ -57,3 +62,26 @@ declare module '*.json' { export default json; /* tslint:enable */ } + +// eth-lightwallet declarations +declare module 'eth-lightwallet' { + export class signing { + public static signTx(keystore: keystore, pwDerivedKey: Uint8Array, rawTx: string, signingAddress: string): string; + public static signMsg(keystore: keystore, pwDerivedKey: Uint8Array, rawMsg: string, signingAddress: string): ECSignatureBuffer; + public static signMsgHash(keystore: keystore, pwDerivedKey: Uint8Array, msgHash: string, signingAddress: string): ECSignatureBuffer; + public static concatSig(signature: any): string; + } + export class keystore { + public static createVault(options: any, callback?: (error: Error, keystore: keystore) => void): keystore; + public static generateRandomSeed(): string; + public static isSeedValid(seed: string): boolean; + public static deserialize(keystore: string): keystore; + public serialize(): string; + public keyFromPassword(password: string, callback?: (error: Error, pwDerivedKey: Uint8Array) => void): Uint8Array; + public isDerivedKeyCorrect(pwDerivedKey: Uint8Array): boolean; + public generateNewAddress(pwDerivedKey: Uint8Array, numberOfAddresses: number): void; + public getSeed(pwDerivedKey: Uint8Array): string; + public exportPrivateKey(address: string, pwDerivedKey: Uint8Array): string; + public getAddresses(): string[]; + } +} diff --git a/packages/subproviders/src/index.ts b/packages/subproviders/src/index.ts index 0e1579706..06d5871f9 100644 --- a/packages/subproviders/src/index.ts +++ b/packages/subproviders/src/index.ts @@ -15,7 +15,7 @@ export { Subprovider } from './subproviders/subprovider'; export { NonceTrackerSubprovider } from './subproviders/nonce_tracker'; export { PrivateKeyWalletSubprovider } from './subproviders/private_key_wallet'; export { MnemonicWalletSubprovider } from './subproviders/mnemonic_wallet'; -export { EthLightwalletSubprovider } from './subproviders/eth_lightwallet'; +export { EthLightwalletSubprovider } from './subproviders/eth_lightwallet_subprovider'; export { Callback, ErrorCallback, diff --git a/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts new file mode 100644 index 000000000..7507eeb49 --- /dev/null +++ b/packages/subproviders/src/subproviders/eth_lightwallet_subprovider.ts @@ -0,0 +1,88 @@ +import { assert } from '@0xproject/assert'; +import { addressUtils } from '@0xproject/utils'; +import * as lightwallet from 'eth-lightwallet'; +import EthereumTx = require('ethereumjs-tx'); +import * as _ from 'lodash'; + +import { PartialTxParams, WalletSubproviderErrors } from '../types'; + +import { BaseWalletSubprovider } from './base_wallet_subprovider'; + +/* + * This class implements the web3-provider-engine subprovider interface and forwards + * requests involving user accounts and signing operations to eth-lightwallet + * + * Source: https://github.com/MetaMask/provider-engine/blob/master/subproviders/subprovider.js + */ +export class EthLightwalletSubprovider extends BaseWalletSubprovider { + private _signing: any; + private _keystore: any; + private _pwDerivedKey: Uint8Array; + + constructor(signing: lightwallet.signing, keystore: lightwallet.keystore, pwDerivedKey: Uint8Array) { + super(); + + this._signing = signing; + this._keystore = keystore; + this._pwDerivedKey = pwDerivedKey; + } + + /** + * Retrieve the accounts associated with the eth-lightwallet instance. + * This method is implicitly called when issuing a `eth_accounts` JSON RPC request + * via your providerEngine instance. + * + * @return An array of accounts + */ + public async getAccountsAsync(): Promise<string[]> { + const accounts = this._keystore.getAddresses(); + return accounts; + } + + /** + * Signs a transaction with the account specificed by the `from` field in txParams. + * If you've added this Subprovider to your app's provider, you can simply send + * an `eth_sendTransaction` 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 txParams Parameters of the transaction to sign + * @return Signed transaction hex string + */ + public async signTransactionAsync(txParams: PartialTxParams): Promise<string> { + if (_.isUndefined(txParams.from) || !addressUtils.isAddress(txParams.from)) { + throw new Error(WalletSubproviderErrors.FromAddressMissingOrInvalid); + } + + const tx = new EthereumTx(txParams); + const txHex = tx.serialize().toString('hex'); + let signedTxHex: string = this._signing.signTx( + this._keystore, this._pwDerivedKey, txHex, txParams.from, this._keystore.hdPathString); + + signedTxHex = `0x${signedTxHex}`; + + return signedTxHex; + } + + /** + * 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. + * @param data Hex string message to sign + * @param address Address of the account to sign with + * @return Signature hex string (order: rsv) + */ + public async signPersonalMessageAsync(data: string, address: string): Promise<string> { + if (_.isUndefined(data)) { + throw new Error(WalletSubproviderErrors.DataMissingForSignPersonalMessage); + } + assert.isHexString('data', data); + assert.isETHAddressHex('address', address); + const result: ECSignatureBuffer = await this._signing.signMsgHash( + this._keystore, this._pwDerivedKey, data, address, this._keystore.hdPathString); + + const signature = this._signing.concatSig(result); + + return signature; + } +} |