Merge branch 'development' into createWethPage
* development: Add additional public changes introduced to changelog Update CHANGELOG Add a comment Introduce a variable for true Remove redundant template string Implement the address derivations Add hdnode dependency Move web3 import after subprovider imports in test web3_factory Fixed https://github.com/0xProject/wiki/issues/19 by disabling re-rendering of markdownCodeBlock renderer if props haven't updated Add convenience `rebuild` command Update website calls to deposit/withdraw Add entry to CHANGELOG
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
"scripts": {
|
||||
"testrpc": "testrpc -p 8545 --networkId 50 -m \"${npm_package_config_mnemonic}\"",
|
||||
"lerna:run": "lerna run",
|
||||
"lerna:rebuild": "lerna run clean; lerna run build;",
|
||||
"lerna:publish": "yarn install; lerna run clean; lerna run build; lerna publish --registry=https://registry.npmjs.org/"
|
||||
},
|
||||
"config": {
|
||||
|
@@ -1,5 +1,11 @@
|
||||
# CHANGELOG
|
||||
|
||||
v0.28.0 - _TBD_
|
||||
------------------------
|
||||
* Add `etherTokenAddress` arg to `depositAsync` and `withdrawAsync` methods on `zeroEx.etherToken` (#267)
|
||||
* Removed accidentally included `unsubscribeAll` method from `zeroEx.proxy`, `zeroEx.etherToken` and `zeroEx.tokenRegistry` (#267)
|
||||
* Removed `etherTokenContractAddress` from `ZeroEx` constructor arg `ZeroExConfig` (#267)
|
||||
|
||||
v0.27.1 - _November 28, 2017_
|
||||
------------------------
|
||||
* Export `TransactionOpts` type
|
||||
|
@@ -82,9 +82,9 @@ describe('ZeroEx library', () => {
|
||||
it('should return true if the signature does pertain to the dataHex & address', async () => {
|
||||
const isValidSignatureLocal = ZeroEx.isValidSignature(dataHex, signature, address);
|
||||
expect(isValidSignatureLocal).to.be.true();
|
||||
const isValidSignatureOnContract = await (zeroEx.exchange as any)
|
||||
._isValidSignatureUsingContractCallAsync(dataHex, signature, address);
|
||||
return expect(isValidSignatureOnContract).to.be.true();
|
||||
return expect(
|
||||
(zeroEx.exchange as any)._isValidSignatureUsingContractCallAsync(dataHex, signature, address),
|
||||
).to.become(true);
|
||||
});
|
||||
});
|
||||
describe('#generateSalt', () => {
|
||||
|
@@ -3,7 +3,6 @@
|
||||
// we are not running in a browser env.
|
||||
// Filed issue: https://github.com/ethereum/web3.js/issues/844
|
||||
(global as any).XMLHttpRequest = undefined;
|
||||
import * as Web3 from 'web3';
|
||||
import ProviderEngine = require('web3-provider-engine');
|
||||
import RpcSubprovider = require('web3-provider-engine/subproviders/rpc');
|
||||
|
||||
@@ -12,6 +11,13 @@ import {FakeGasEstimateSubprovider} from './subproviders/fake_gas_estimate_subpr
|
||||
|
||||
import {constants} from './constants';
|
||||
|
||||
// HACK: web3 leaks XMLHttpRequest into the global scope and causes requests to hang
|
||||
// because they are using the wrong XHR package.
|
||||
// importing web3 after subproviders fixes this issue
|
||||
// Filed issue: https://github.com/ethereum/web3.js/issues/844
|
||||
// tslint:disable-next-line:ordered-imports
|
||||
import * as Web3 from 'web3';
|
||||
|
||||
export const web3Factory = {
|
||||
create(hasAddresses: boolean = true): Web3 {
|
||||
const provider = this.getRpcProvider(hasAddresses);
|
||||
|
@@ -13,7 +13,7 @@ import {ZRXRequestQueue} from './zrx_request_queue';
|
||||
|
||||
// HACK: web3 leaks XMLHttpRequest into the global scope and causes requests to hang
|
||||
// because they are using the wrong XHR package.
|
||||
// Issue: https://github.com/trufflesuite/truffle-contract/issues/14
|
||||
// Filed issue: https://github.com/ethereum/web3.js/issues/844
|
||||
// tslint:disable-next-line:ordered-imports
|
||||
import * as Web3 from 'web3';
|
||||
|
||||
|
@@ -3,7 +3,7 @@ import * as timers from 'timers';
|
||||
|
||||
// HACK: web3 leaks XMLHttpRequest into the global scope and causes requests to hang
|
||||
// because they are using the wrong XHR package.
|
||||
// Issue: https://github.com/trufflesuite/truffle-contract/issues/14
|
||||
// Filed issue: https://github.com/ethereum/web3.js/issues/844
|
||||
// tslint:disable-next-line:ordered-imports
|
||||
import * as Web3 from 'web3';
|
||||
|
||||
|
@@ -9,7 +9,7 @@ import {utils} from './utils';
|
||||
|
||||
// HACK: web3 leaks XMLHttpRequest into the global scope and causes requests to hang
|
||||
// because they are using the wrong XHR package.
|
||||
// Issue: https://github.com/trufflesuite/truffle-contract/issues/14
|
||||
// Filed issue: https://github.com/ethereum/web3.js/issues/844
|
||||
// tslint:disable-next-line:ordered-imports
|
||||
import * as Web3 from 'web3';
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
# CHANGELOG
|
||||
|
||||
vx.x.x
|
||||
v0.x.x - _TBD, 2017_
|
||||
------------------------
|
||||
* Improve the performance of address fetching (#271)
|
||||
|
@@ -23,6 +23,7 @@
|
||||
"es6-promisify": "^5.0.0",
|
||||
"ethereumjs-tx": "^1.3.3",
|
||||
"ethereumjs-util": "^5.1.1",
|
||||
"hdkey": "^0.7.1",
|
||||
"ledgerco": "0xProject/ledger-node-js-api",
|
||||
"lodash": "^4.17.4",
|
||||
"semaphore-async-await": "^1.5.1",
|
||||
|
13
packages/subproviders/src/globals.d.ts
vendored
13
packages/subproviders/src/globals.d.ts
vendored
@@ -48,7 +48,7 @@ declare module 'ledgerco' {
|
||||
public comm: comm;
|
||||
constructor(comm: comm);
|
||||
public getAddress_async(path: string, display?: boolean, chaincode?: boolean):
|
||||
Promise<{publicKey: string; address: string}>;
|
||||
Promise<{publicKey: string; address: string; chainCode: string}>;
|
||||
public signTransaction_async(path: string, rawTxHex: string): Promise<ECSignatureString>;
|
||||
public getAppConfiguration_async(): Promise<{ arbitraryDataEnabled: number; version: string }>;
|
||||
public signPersonalMessage_async(path: string, messageHex: string): Promise<ECSignature>;
|
||||
@@ -91,3 +91,14 @@ declare module 'web3-provider-engine' {
|
||||
}
|
||||
export = Web3ProviderEngine;
|
||||
}
|
||||
|
||||
// hdkey declarations
|
||||
declare module 'hdkey' {
|
||||
class HDNode {
|
||||
public publicKey: Buffer;
|
||||
public chainCode: Buffer;
|
||||
public constructor();
|
||||
public derive(path: string): HDNode;
|
||||
}
|
||||
export = HDNode;
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ import {assert} from '@0xproject/assert';
|
||||
import {addressUtils} from '@0xproject/utils';
|
||||
import EthereumTx = require('ethereumjs-tx');
|
||||
import ethUtil = require('ethereumjs-util');
|
||||
import HDNode = require('hdkey');
|
||||
import * as _ from 'lodash';
|
||||
import Semaphore from 'semaphore-async-await';
|
||||
import Web3 = require('web3');
|
||||
@@ -20,7 +21,7 @@ import {Subprovider} from './subprovider';
|
||||
const DEFAULT_DERIVATION_PATH = `44'/60'/0'`;
|
||||
const NUM_ADDRESSES_TO_FETCH = 10;
|
||||
const ASK_FOR_ON_DEVICE_CONFIRMATION = false;
|
||||
const SHOULD_GET_CHAIN_CODE = false;
|
||||
const SHOULD_GET_CHAIN_CODE = true;
|
||||
|
||||
export class LedgerSubprovider extends Subprovider {
|
||||
private _nonceLock: Semaphore;
|
||||
@@ -127,21 +128,30 @@ export class LedgerSubprovider extends Subprovider {
|
||||
public async getAccountsAsync(): Promise<string[]> {
|
||||
this._ledgerClientIfExists = await this.createLedgerClientAsync();
|
||||
|
||||
// TODO: replace with generating addresses without hitting Ledger
|
||||
let ledgerResponse;
|
||||
try {
|
||||
ledgerResponse = await this._ledgerClientIfExists.getAddress_async(
|
||||
this._derivationPath, this._shouldAlwaysAskForConfirmation, SHOULD_GET_CHAIN_CODE,
|
||||
);
|
||||
} finally {
|
||||
await this.destoryLedgerClientAsync();
|
||||
}
|
||||
|
||||
const hdKey = new HDNode();
|
||||
hdKey.publicKey = new Buffer(ledgerResponse.publicKey, 'hex');
|
||||
hdKey.chainCode = new Buffer(ledgerResponse.chainCode, 'hex');
|
||||
|
||||
const accounts = [];
|
||||
for (let i = 0; i < NUM_ADDRESSES_TO_FETCH; i++) {
|
||||
try {
|
||||
const derivationPath = `${this._derivationPath}/${i + this._derivationPathIndex}`;
|
||||
const result = await this._ledgerClientIfExists.getAddress_async(
|
||||
derivationPath, this._shouldAlwaysAskForConfirmation, SHOULD_GET_CHAIN_CODE,
|
||||
);
|
||||
accounts.push(result.address.toLowerCase());
|
||||
} catch (err) {
|
||||
await this.destoryLedgerClientAsync();
|
||||
throw err;
|
||||
}
|
||||
const derivedHDNode = hdKey.derive(`m/${i + this._derivationPathIndex}`);
|
||||
const derivedPublicKey = derivedHDNode.publicKey;
|
||||
const shouldSanitizePublicKey = true;
|
||||
const ethereumAddressUnprefixed = ethUtil.publicToAddress(
|
||||
derivedPublicKey, shouldSanitizePublicKey,
|
||||
).toString('hex');
|
||||
const ethereumAddressPrefixed = ethUtil.addHexPrefix(ethereumAddressUnprefixed);
|
||||
accounts.push(ethereumAddressPrefixed.toLowerCase());
|
||||
}
|
||||
await this.destoryLedgerClientAsync();
|
||||
return accounts;
|
||||
}
|
||||
public async signTransactionAsync(txParams: PartialTxParams): Promise<string> {
|
||||
|
@@ -10,8 +10,10 @@ export interface LedgerCommunicationClient {
|
||||
* NodeJs and Browser communication are supported.
|
||||
*/
|
||||
export interface LedgerEthereumClient {
|
||||
// shouldGetChainCode is defined as `true` instead of `boolean` because other types rely on the assumption
|
||||
// that we get back the chain code and we don't have dependent types to express it properly
|
||||
getAddress_async: (derivationPath: string, askForDeviceConfirmation: boolean,
|
||||
shouldGetChainCode: boolean) => Promise<LedgerGetAddressResult>;
|
||||
shouldGetChainCode: true) => Promise<LedgerGetAddressResult>;
|
||||
signPersonalMessage_async: (derivationPath: string, messageHex: string) => Promise<ECSignature>;
|
||||
signTransaction_async: (derivationPath: string, txHex: string) => Promise<ECSignatureString>;
|
||||
comm: LedgerCommunicationClient;
|
||||
@@ -63,6 +65,8 @@ export interface SignatureData {
|
||||
|
||||
export interface LedgerGetAddressResult {
|
||||
address: string;
|
||||
publicKey: string;
|
||||
chainCode: string;
|
||||
}
|
||||
|
||||
export interface LedgerWalletSubprovider {
|
||||
|
@@ -18,7 +18,7 @@ import {reportCallbackErrors} from '../utils/report_callback_errors';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
const FAKE_ADDRESS = '0x9901c66f2d4b95f7074b553da78084d708beca70';
|
||||
const FAKE_ADDRESS = '0xb088a3bc93f71b4de97b9de773e9647645983688';
|
||||
|
||||
describe('LedgerSubprovider', () => {
|
||||
const networkId: number = 42;
|
||||
@@ -28,8 +28,14 @@ describe('LedgerSubprovider', () => {
|
||||
// tslint:disable:no-object-literal-type-assertion
|
||||
const ledgerEthClient = {
|
||||
getAddress_async: async () => {
|
||||
// tslint:disable-next-line:max-line-length
|
||||
const publicKey = '04f428290f4c5ed6a198f71b8205f488141dbb3f0840c923bbfa798ecbee6370986c03b5575d94d506772fb48a6a44e345e4ebd4f028a6f609c44b655d6d3e71a1';
|
||||
const chainCode = 'ac055a5537c0c7e9e02d14a197cad6b857836da2a12043b46912a37d959b5ae8';
|
||||
const address = '0xBa388BA5e5EEF2c6cE42d831c2B3A28D3c99bdB1';
|
||||
return {
|
||||
address: FAKE_ADDRESS,
|
||||
publicKey,
|
||||
address,
|
||||
chainCode,
|
||||
};
|
||||
},
|
||||
signPersonalMessage_async: async () => {
|
||||
|
@@ -7,14 +7,23 @@ interface MarkdownCodeBlockProps {
|
||||
language: string;
|
||||
}
|
||||
|
||||
export function MarkdownCodeBlock(props: MarkdownCodeBlockProps) {
|
||||
return (
|
||||
<span style={{fontSize: 16}}>
|
||||
<HighLight
|
||||
className={props.language || 'js'}
|
||||
>
|
||||
{props.literal}
|
||||
</HighLight>
|
||||
</span>
|
||||
);
|
||||
interface MarkdownCodeBlockState {}
|
||||
|
||||
export class MarkdownCodeBlock extends React.Component<MarkdownCodeBlockProps, MarkdownCodeBlockState> {
|
||||
// Re-rendering a codeblock causes any use selection to become de-selected. This is annoying when trying
|
||||
// to copy-paste code examples. We therefore noop re-renders on this component if it's props haven't changed.
|
||||
public shouldComponentUpdate(nextProps: MarkdownCodeBlockProps, nextState: MarkdownCodeBlockState) {
|
||||
return nextProps.literal !== this.props.literal || nextProps.language !== this.props.language;
|
||||
}
|
||||
public render() {
|
||||
return (
|
||||
<span style={{fontSize: 16}}>
|
||||
<HighLight
|
||||
className={this.props.language || 'javascript'}
|
||||
>
|
||||
{this.props.literal}
|
||||
</HighLight>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user