From 1fdbcfa5de5330a00a72d61516bfe9b7d1013b71 Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Thu, 22 Nov 2018 14:07:35 +0100 Subject: [PATCH 01/13] Use strict in TS --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 2d716167..6ca9fdbd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,7 @@ "declaration": true, "lib": ["dom", "es2015", "es2017"], "moduleResolution": "node", - "noImplicitAny": true, + "strict": true, "target": "es5" }, "exclude": ["*.spec.ts"] From 71aa35760d0d7ac83590d35c518e08a2e72ccfc3 Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Thu, 22 Nov 2018 14:14:06 +0100 Subject: [PATCH 02/13] Remove tslint prettier --- package.json | 1 - tslint.json | 2 +- yarn.lock | 5 ----- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/package.json b/package.json index 5020c080..717ba8ef 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,6 @@ "rimraf": "^2.6.2", "ts-jest": "^23.0.0", "tslint": "^5.10.0", - "tslint-config-prettier": "^1.14.0", "tslint-config-semistandard": "^7.0.0", "typedoc": "^0.12.0", "typedoc-plugin-markdown": "^1.1.13", diff --git a/tslint.json b/tslint.json index c86026fe..4281b8e2 100644 --- a/tslint.json +++ b/tslint.json @@ -1,5 +1,5 @@ { - "extends": ["tslint-config-semistandard", "tslint-config-prettier"], + "extends": ["tslint-config-semistandard"], "linterOptions": { "exclude": ["**/node_modules/**/*", "**/lib/**/*", "**/example/**/*"] } diff --git a/yarn.lock b/yarn.lock index 0c0010f3..bb65ae55 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5789,11 +5789,6 @@ tslib@^1.0.0, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== -tslint-config-prettier@^1.14.0: - version "1.14.0" - resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.14.0.tgz#860b36634e53f4c70c64c51ff3ef7fd9bbab7676" - integrity sha512-SomD+aLvAwoihMtyCfkhhWKt9wcpSY2ZpgDV6OuxLYi8+7uOwE2g03aa+jJLSmY0Ys8s3ZLM5Iwfuwu3giCSQQ== - tslint-config-semistandard@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/tslint-config-semistandard/-/tslint-config-semistandard-7.0.0.tgz#c2d3214b6282a4fed07e875dd9f0691be4e832f1" From 916211f574210f0f12419225d2762e69ce7c4863 Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Thu, 22 Nov 2018 14:15:01 +0100 Subject: [PATCH 03/13] Fix types using strict in abi --- packages/abi/src/decoder/decoder.spec.ts | 34 +++++++++++----- packages/abi/src/decoder/decoder.ts | 40 ++++++++++++------- packages/abi/src/encoder/encoder.ts | 6 +-- .../src/spec/event/decodedLogParam.spec.ts | 2 +- packages/abi/src/spec/event/event.spec.ts | 10 ++--- packages/abi/src/spec/event/event.ts | 10 ++++- packages/abi/src/spec/function.ts | 10 ++++- packages/abi/src/spec/param.ts | 2 +- .../abi/src/spec/paramType/format.spec.ts | 40 +++++++++++++++++-- packages/abi/src/spec/paramType/format.ts | 26 ++++++++---- .../abi/src/spec/paramType/paramType.spec.ts | 6 +-- packages/abi/src/spec/paramType/paramType.ts | 4 +- packages/abi/src/token/token.ts | 2 +- packages/abi/src/types.ts | 4 +- packages/abi/src/util/address.ts | 4 +- packages/abi/src/util/signature.spec.ts | 24 ++++++----- packages/abi/src/util/signature.ts | 17 ++++++-- packages/abi/src/util/slice.spec.ts | 6 +++ packages/abi/src/util/slice.ts | 2 +- 19 files changed, 179 insertions(+), 70 deletions(-) diff --git a/packages/abi/src/decoder/decoder.spec.ts b/packages/abi/src/decoder/decoder.spec.ts index cc0298d1..6e1ee6e2 100644 --- a/packages/abi/src/decoder/decoder.spec.ts +++ b/packages/abi/src/decoder/decoder.spec.ts @@ -12,7 +12,11 @@ import { padU32 } from '../util/pad'; describe('decoder/Decoder', () => { const stringToBytes = function (str: string) { - return str.match(/.{1,2}/g).map(code => parseInt(code, 16)); + const matches = str.match(/.{1,2}/g); + if (!matches) { + throw new Error('stringToBytes: mo matches'); + } + return matches.map(code => parseInt(code, 16)); }; const address1 = @@ -118,9 +122,9 @@ describe('decoder/Decoder', () => { describe('decodeParam', () => { it('throws an error on non ParamType param', () => { - expect(() => Decoder.decodeParam({} as ParamType, undefined, undefined)).toThrow( - /ParamType/ - ); + expect(() => + Decoder.decodeParam({} as ParamType, undefined, undefined) + ).toThrow(/ParamType/); }); it('throws an error on invalid param type', () => { @@ -172,8 +176,11 @@ describe('decoder/Decoder', () => { it('decodes fixedBytes', () => { expect( - Decoder.decodeParam(new ParamType('fixedBytes', null, 2), [bytes1], 0) - .token + Decoder.decodeParam( + new ParamType('fixedBytes', undefined, 2), + [bytes1], + 0 + ).token ).toEqual(tokenFixedBytes1); }); @@ -209,10 +216,14 @@ describe('decoder/Decoder', () => { it('decodes string (indexed)', () => { expect( - Decoder.decodeParam(new ParamType('string', null, 0, true), [bytes1], 0) + Decoder.decodeParam( + new ParamType('string', undefined, 0, true), + [bytes1], + 0 + ) ).toEqual( Decoder.decodeParam( - new ParamType('fixedBytes', null, 32, true), + new ParamType('fixedBytes', undefined, 32, true), [bytes1], 0 ) @@ -222,7 +233,7 @@ describe('decoder/Decoder', () => { describe('decode', () => { it('throws an error on invalid params', () => { - expect(() => Decoder.decode(null, '123')).toThrow(/array/); + expect(() => Decoder.decode(undefined, '123')).toThrow(/array/); }); describe('address', () => { @@ -300,7 +311,10 @@ describe('decoder/Decoder', () => { describe('fixedBytes', () => { it('decodes fixedBytes', () => { expect( - Decoder.decode([new ParamType('fixedBytes', null, 2)], `${bytes1}`) + Decoder.decode( + [new ParamType('fixedBytes', undefined, 2)], + `${bytes1}` + ) ).toEqual([tokenFixedBytes1]); }); }); diff --git a/packages/abi/src/decoder/decoder.ts b/packages/abi/src/decoder/decoder.ts index 1ba9a9cf..b3534ce0 100644 --- a/packages/abi/src/decoder/decoder.ts +++ b/packages/abi/src/decoder/decoder.ts @@ -12,12 +12,12 @@ import ParamType from '../spec/paramType/paramType'; import { sliceData } from '../util/slice'; import { asAddress, asBool, asI32, asU32 } from '../util/sliceAs'; import { isArray, isInstanceOf } from '../util/types'; -import { TokenValue } from '../types'; +import { Slices } from '../types'; const NULL = '0000000000000000000000000000000000000000000000000000000000000000'; class Decoder { - static decode (params: ParamType[], data: string) { + static decode (params: ParamType[] | undefined, data: string) { if (!isArray(params)) { throw new Error('Parameters should be array of ParamType'); } @@ -33,7 +33,7 @@ class Decoder { }); } - static peek (slices: string[], position: number) { + static peek (slices: Slices, position: number) { if (!slices || !slices[position]) { return NULL; } @@ -41,7 +41,7 @@ class Decoder { return slices[position]; } - static takeBytes (slices: string[], position: number, length: number) { + static takeBytes (slices: Slices, position: number, length: number) { const slicesLength = Math.floor((length + 31) / 32); let bytesStr = ''; @@ -58,8 +58,8 @@ class Decoder { static decodeParam ( param: ParamType, - slices: string[], - offset: number + slices: Slices, + offset: number = 0 ): DecodeResult { if (!isInstanceOf(param, ParamType)) { throw new Error('param should be instanceof ParamType'); @@ -96,15 +96,15 @@ class Decoder { offset + 1 ); - case 'fixedBytes': + case 'fixedBytes': { taken = Decoder.takeBytes(slices, offset, param.length); return new DecodeResult( new Token(param.type, taken.bytes), taken.newOffset ); - - case 'bytes': + } + case 'bytes': { lengthOffset = asU32(Decoder.peek(slices, offset)) .div(32) .toNumber(); @@ -112,8 +112,8 @@ class Decoder { taken = Decoder.takeBytes(slices, lengthOffset + 1, length); return new DecodeResult(new Token(param.type, taken.bytes), offset + 1); - - case 'string': + } + case 'string': { if (param.indexed) { taken = Decoder.takeBytes(slices, offset, 32); @@ -142,8 +142,14 @@ class Decoder { } return new DecodeResult(new Token(param.type, decoded), offset + 1); + } + case 'array': { + if (!param.subtype) { + throw new Error( + `decodeParam: param of type '${param.type}' must have a subtype` + ); + } - case 'array': lengthOffset = asU32(Decoder.peek(slices, offset)) .div(32) .toNumber(); @@ -158,8 +164,14 @@ class Decoder { } return new DecodeResult(new Token(param.type, tokens), offset + 1); + } + case 'fixedArray': { + if (!param.subtype) { + throw new Error( + `decodeParam: param of type '${param.type}' must have a subtype` + ); + } - case 'fixedArray': newOffset = offset; for (let index = 0; index < param.length; index++) { @@ -170,7 +182,7 @@ class Decoder { } return new DecodeResult(new Token(param.type, tokens), newOffset); - + } default: throw new Error(`Invalid param type ${param.type} in decodeParam`); } diff --git a/packages/abi/src/encoder/encoder.ts b/packages/abi/src/encoder/encoder.ts index 6c32fb82..780f3233 100644 --- a/packages/abi/src/encoder/encoder.ts +++ b/packages/abi/src/encoder/encoder.ts @@ -24,7 +24,7 @@ import { } from '../types'; class Encoder { - static encode (tokens: Token[]) { + static encode (tokens?: Token[]) { if (!isArray(tokens)) { throw new Error('tokens should be array of Token'); } @@ -44,8 +44,8 @@ class Encoder { return `${inits}${closings}`; } - static encodeToken (token: Token, index = 0): Mediate { - if (!isInstanceOf(token, Token)) { + static encodeToken (token?: Token, index = 0): Mediate { + if (!token || !isInstanceOf(token, Token)) { throw new Error('token should be instanceof Token'); } diff --git a/packages/abi/src/spec/event/decodedLogParam.spec.ts b/packages/abi/src/spec/event/decodedLogParam.spec.ts index 9ccbc9b8..aa3954b8 100644 --- a/packages/abi/src/spec/event/decodedLogParam.spec.ts +++ b/packages/abi/src/spec/event/decodedLogParam.spec.ts @@ -14,7 +14,7 @@ describe('spec/event/DecodedLogParam', () => { it('disallows kind not instanceof ParamType', () => { expect( - () => new DecodedLogParam('test', 'param' as any, undefined) + () => new DecodedLogParam('test', 'param' as any, undefined as any) ).toThrow(/ParamType/); }); diff --git a/packages/abi/src/spec/event/event.spec.ts b/packages/abi/src/spec/event/event.spec.ts index a8283f35..34c7f81a 100644 --- a/packages/abi/src/spec/event/event.spec.ts +++ b/packages/abi/src/spec/event/event.spec.ts @@ -51,7 +51,7 @@ describe('spec/event/Event', () => { it('returns all the types', () => { expect(event.inputParamTypes()).toEqual([ new ParamType('bool'), - new ParamType('uint', null, 256, true) + new ParamType('uint', undefined, 256, true) ]); }); }); @@ -98,12 +98,12 @@ describe('spec/event/Event', () => { expect(decoded.params).toEqual([ new DecodedLogParam( 'a', - new ParamType('int', null, 256), + new ParamType('int', undefined, 256), new Token('int', new BigNumber(3)) ), new DecodedLogParam( 'b', - new ParamType('int', null, 256, true), + new ParamType('int', undefined, 256, true), new Token('int', new BigNumber(2)) ), new DecodedLogParam( @@ -113,7 +113,7 @@ describe('spec/event/Event', () => { ), new DecodedLogParam( 'd', - new ParamType('address', null, 0, true), + new ParamType('address', undefined, 0, true), new Token('address', '0x1111111111111111111111111111111111111111') ) ]); @@ -134,7 +134,7 @@ describe('spec/event/Event', () => { expect(decoded.params).toEqual([ new DecodedLogParam( 'a', - new ParamType('int', null, 256), + new ParamType('int', undefined, 256), new Token('int', new BigNumber(3)) ) ]); diff --git a/packages/abi/src/spec/event/event.ts b/packages/abi/src/spec/event/event.ts index 5206ecf9..b178fc8b 100644 --- a/packages/abi/src/spec/event/event.ts +++ b/packages/abi/src/spec/event/event.ts @@ -28,6 +28,14 @@ class Event { this.inputParamTypes() ); + if (!name) { + throw new Error( + `Event constructor: abi item does not have a name: ${JSON.stringify( + abi + )}` + ); + } + this._id = id; this._name = name; this._signature = signature; @@ -69,7 +77,7 @@ class Event { const topicParams = this.indexedParams(true); const dataParams = this.indexedParams(false); - let address; + let address = ''; let toSkip: number; if (!this.anonymous) { diff --git a/packages/abi/src/spec/function.ts b/packages/abi/src/spec/function.ts index a7ed713d..b046c802 100644 --- a/packages/abi/src/spec/function.ts +++ b/packages/abi/src/spec/function.ts @@ -23,7 +23,7 @@ class Func { constructor (abi: AbiItem) { this._abi = abi; this._constant = !!abi.constant; - this._payable = abi.payable; + this._payable = abi.payable || false; this._inputs = Param.toParams(abi.inputs || []); this._outputs = Param.toParams(abi.outputs || []); @@ -32,6 +32,14 @@ class Func { this.inputParamTypes() ); + if (!name) { + throw new Error( + `Event constructor: abi item does not have a name: ${JSON.stringify( + abi + )}` + ); + } + this._id = id; this._name = name; this._signature = signature; diff --git a/packages/abi/src/spec/param.ts b/packages/abi/src/spec/param.ts index 41e4d20f..aef311d2 100644 --- a/packages/abi/src/spec/param.ts +++ b/packages/abi/src/spec/param.ts @@ -3,7 +3,7 @@ // // SPDX-License-Identifier: MIT -import { AbiInput, TokenTypeEnum } from '../types'; +import { AbiInput } from '../types'; import ParamType from './paramType'; import { toParamType } from './paramType/format'; diff --git a/packages/abi/src/spec/paramType/format.spec.ts b/packages/abi/src/spec/paramType/format.spec.ts index 63b40af5..a6965529 100644 --- a/packages/abi/src/spec/paramType/format.spec.ts +++ b/packages/abi/src/spec/paramType/format.spec.ts @@ -45,19 +45,19 @@ describe('spec/paramType/format', () => { describe('length types', () => { it('converts int32 to int32', () => { - const pt = new ParamType('int', null, 32); + const pt = new ParamType('int', undefined, 32); expect(fromParamType(pt)).toEqual('int32'); }); it('converts uint64 to int64', () => { - const pt = new ParamType('uint', null, 64); + const pt = new ParamType('uint', undefined, 64); expect(fromParamType(pt)).toEqual('uint64'); }); it('converts fixedBytes8 to bytes8', () => { - const pt = new ParamType('fixedBytes', null, 8); + const pt = new ParamType('fixedBytes', undefined, 8); expect(fromParamType(pt)).toEqual('bytes8'); }); @@ -171,6 +171,9 @@ describe('spec/paramType/format', () => { describe('fixed arrays', () => { it('creates fixed array', () => { const pt = toParamType('bytes[8]'); + if (!pt.subtype) { + throw new Error('No subtype.'); + } expect(pt.type).toEqual('fixedArray'); expect(pt.subtype.type).toEqual('bytes'); @@ -179,11 +182,18 @@ describe('spec/paramType/format', () => { it('creates fixed arrays of fixed arrays', () => { const pt = toParamType('bytes[45][3]'); + if (!pt.subtype) { + throw new Error('No subtype.'); + } expect(pt.type).toEqual('fixedArray'); expect(pt.length).toEqual(3); expect(pt.subtype.type).toEqual('fixedArray'); expect(pt.subtype.length).toEqual(45); + + if (!pt.subtype.subtype) { + throw new Error('No subtype.'); + } expect(pt.subtype.subtype.type).toEqual('bytes'); }); }); @@ -191,6 +201,9 @@ describe('spec/paramType/format', () => { describe('dynamic arrays', () => { it('creates a dynamic array', () => { const pt = toParamType('bytes[]'); + if (!pt.subtype) { + throw new Error('No subtype.'); + } expect(pt.type).toEqual('array'); expect(pt.subtype.type).toEqual('bytes'); @@ -198,9 +211,16 @@ describe('spec/paramType/format', () => { it('creates a dynamic array of dynamic arrays', () => { const pt = toParamType('bool[][]'); + if (!pt.subtype) { + throw new Error('No subtype.'); + } expect(pt.type).toEqual('array'); expect(pt.subtype.type).toEqual('array'); + + if (!pt.subtype.subtype) { + throw new Error('No subtype.'); + } expect(pt.subtype.subtype.type).toEqual('bool'); }); }); @@ -208,19 +228,33 @@ describe('spec/paramType/format', () => { describe('mixed arrays', () => { it('creates a fixed dynamic array', () => { const pt = toParamType('bool[][3]'); + if (!pt.subtype) { + throw new Error('No subtype.'); + } expect(pt.type).toEqual('fixedArray'); expect(pt.length).toEqual(3); expect(pt.subtype.type).toEqual('array'); + + if (!pt.subtype.subtype) { + throw new Error('No subtype.'); + } expect(pt.subtype.subtype.type).toEqual('bool'); }); it('creates a dynamic fixed array', () => { const pt = toParamType('bool[3][]'); + if (!pt.subtype) { + throw new Error('No subtype.'); + } expect(pt.type).toEqual('array'); expect(pt.subtype.type).toEqual('fixedArray'); expect(pt.subtype.length).toEqual(3); + + if (!pt.subtype.subtype) { + throw new Error('No subtype.'); + } expect(pt.subtype.subtype.type).toEqual('bool'); }); }); diff --git a/packages/abi/src/spec/paramType/format.ts b/packages/abi/src/spec/paramType/format.ts index 2ecf9299..0e824f69 100644 --- a/packages/abi/src/spec/paramType/format.ts +++ b/packages/abi/src/spec/paramType/format.ts @@ -30,31 +30,31 @@ export const toParamType = (type: string, indexed?: boolean): ParamType => { case 'bool': case 'bytes': case 'string': - return new ParamType(type, null, 0, indexed); + return new ParamType(type, undefined, 0, indexed); case 'int': case 'uint': - return new ParamType(type, null, 256, indexed); + return new ParamType(type, undefined, 256, indexed); default: if (type.indexOf('uint') === 0) { return new ParamType( 'uint', - null, + undefined, parseInt(type.substr(4), 10), indexed ); } else if (type.indexOf('int') === 0) { return new ParamType( 'int', - null, + undefined, parseInt(type.substr(3), 10), indexed ); } else if (type.indexOf('bytes') === 0) { return new ParamType( 'fixedBytes', - null, + undefined, parseInt(type.substr(5), 10), indexed ); @@ -84,11 +84,23 @@ export const fromParamType = (paramType: ParamType): string => { case 'fixedBytes': return `bytes${paramType.length}`; - case 'fixedArray': + case 'fixedArray': { + if (!paramType.subtype) { + throw new Error( + `decodeParam: param of type '${paramType.type}' must have a subtype` + ); + } return `${fromParamType(paramType.subtype)}[${paramType.length}]`; + } - case 'array': + case 'array': { + if (!paramType.subtype) { + throw new Error( + `decodeParam: param of type '${paramType.type}' must have a subtype` + ); + } return `${fromParamType(paramType.subtype)}[]`; + } default: throw new Error(`Cannot convert from ParamType ${paramType.type}`); diff --git a/packages/abi/src/spec/paramType/paramType.spec.ts b/packages/abi/src/spec/paramType/paramType.spec.ts index f9bd78cf..8c952ba7 100644 --- a/packages/abi/src/spec/paramType/paramType.spec.ts +++ b/packages/abi/src/spec/paramType/paramType.spec.ts @@ -59,14 +59,14 @@ describe('spec/paramType/ParamType', () => { }); it('sets the type of the object', () => { - expect(new ParamType('bool', null, 1).type).toEqual('bool'); + expect(new ParamType('bool', undefined, 1).type).toEqual('bool'); }); it('sets the subtype of the object', () => { expect(new ParamType('array', new ParamType('bool'), 1).subtype).toEqual({ _indexed: false, _length: 0, - _subtype: null, + _subtype: undefined, _type: 'bool' }); }); @@ -86,7 +86,7 @@ describe('spec/paramType/ParamType', () => { it('sets default values where none supplied', () => { expect(Object.values(new ParamType('string'))).toEqual([ 'string', - null, + undefined, 0, false ]); diff --git a/packages/abi/src/spec/paramType/paramType.ts b/packages/abi/src/spec/paramType/paramType.ts index 176e82a6..5c5b3b37 100644 --- a/packages/abi/src/spec/paramType/paramType.ts +++ b/packages/abi/src/spec/paramType/paramType.ts @@ -8,13 +8,13 @@ import TYPES from './types'; class ParamType { private _indexed?: boolean; - private _length?: number; + private _length: number; private _subtype?: ParamType; private _type: TokenTypeEnum; constructor ( type: TokenTypeEnum, - subtype: ParamType = null, + subtype: ParamType | undefined = undefined, length = 0, indexed = false ) { diff --git a/packages/abi/src/token/token.ts b/packages/abi/src/token/token.ts index 5d5d4a7d..362f3e22 100644 --- a/packages/abi/src/token/token.ts +++ b/packages/abi/src/token/token.ts @@ -8,7 +8,7 @@ import TYPES from '../spec/paramType/types'; class Token { private _type: TokenTypeEnum; - private _value: TokenValue; + private _value: TokenValue | undefined; constructor (type: TokenTypeEnum, value?: TokenValue) { Token.validateType(type); diff --git a/packages/abi/src/types.ts b/packages/abi/src/types.ts index 7716531b..af69c482 100644 --- a/packages/abi/src/types.ts +++ b/packages/abi/src/types.ts @@ -9,7 +9,7 @@ import Token from './token'; export interface AbiInput { indexed?: boolean; - name?: string; + name: string; type: TokenTypeEnum; } @@ -17,6 +17,8 @@ export type AbiItemType = 'function' | 'event' | 'constructor' | 'fallback'; export type MediateType = 'raw' | 'prefixed' | 'fixedArray' | 'array'; +export type Slices = string[] | null | undefined; + // Elementary types export type TokenTypeEnum = | 'address' diff --git a/packages/abi/src/util/address.ts b/packages/abi/src/util/address.ts index 94372d35..b36b9c9b 100644 --- a/packages/abi/src/util/address.ts +++ b/packages/abi/src/util/address.ts @@ -55,8 +55,8 @@ export const isAddress = (address: string) => { * * @param address - The address to convert. */ -export const toChecksumAddress = (address: string) => { - const _address = (address || '').toLowerCase(); +export const toChecksumAddress = (address: string = '') => { + const _address = address.toLowerCase(); if (!isAddress(_address)) { return ''; diff --git a/packages/abi/src/util/signature.spec.ts b/packages/abi/src/util/signature.spec.ts index afb7166c..7f25a9bc 100644 --- a/packages/abi/src/util/signature.spec.ts +++ b/packages/abi/src/util/signature.spec.ts @@ -18,7 +18,9 @@ describe('util/signature', () => { }); it('encodes signature baz(uint32) correctly', () => { - expect(eventSignature('baz', [new ParamType('uint', null, 32)])).toEqual({ + expect( + eventSignature('baz', [new ParamType('uint', undefined, 32)]) + ).toEqual({ id: 'baz(uint32)', name: 'baz', signature: @@ -29,7 +31,7 @@ describe('util/signature', () => { it('encodes signature baz(uint32, bool) correctly', () => { expect( eventSignature('baz', [ - new ParamType('uint', null, 32), + new ParamType('uint', undefined, 32), new ParamType('bool') ]) ).toEqual({ @@ -67,19 +69,19 @@ describe('util/signature', () => { }); it('encodes signature baz(uint32) correctly', () => { - expect(methodSignature('baz', [new ParamType('uint', null, 32)])).toEqual( - { - id: 'baz(uint32)', - name: 'baz', - signature: '7d68785e' - } - ); + expect( + methodSignature('baz', [new ParamType('uint', undefined, 32)]) + ).toEqual({ + id: 'baz(uint32)', + name: 'baz', + signature: '7d68785e' + }); }); it('encodes signature baz(uint32, bool) correctly', () => { expect( methodSignature('baz', [ - new ParamType('uint', null, 32), + new ParamType('uint', undefined, 32), new ParamType('bool') ]) ).toEqual({ @@ -92,7 +94,7 @@ describe('util/signature', () => { it('encodes signature in name correctly', () => { expect( methodSignature('baz(uint32,bool)', [ - new ParamType('uint', null, 32), + new ParamType('uint', undefined, 32), new ParamType('bool') ]) ).toEqual({ diff --git a/packages/abi/src/util/signature.ts b/packages/abi/src/util/signature.ts index 2165e9a3..e0f0c864 100644 --- a/packages/abi/src/util/signature.ts +++ b/packages/abi/src/util/signature.ts @@ -11,7 +11,10 @@ import ParamType from '../spec/paramType'; /** * Get event signature. */ -export const eventSignature = (eventName: string, params: ParamType[]) => { +export const eventSignature = ( + eventName: string | undefined, + params: ParamType[] = [] +) => { const { strName, name } = parseName(eventName); const types = (params || []).map(fromParamType).join(','); const id = `${strName}(${types})`; @@ -26,7 +29,10 @@ export const eventSignature = (eventName: string, params: ParamType[]) => { * @param methodName - The method name. * @param params - The list of params */ -export const methodSignature = (methodName: string, params: ParamType[]) => { +export const methodSignature = ( + methodName: string | undefined, + params: ParamType[] = [] +) => { const { id, name, signature } = eventSignature(methodName, params); return { id, name, signature: signature.substr(0, 8) }; @@ -37,7 +43,12 @@ export const methodSignature = (methodName: string, params: ParamType[]) => { * * @param name - Name to parse. */ -export const parseName = (name: string) => { +export const parseName = ( + name: string | undefined +): { + strName: string; + name: string; +} => { const strName = `${name || ''}`; const index = strName.indexOf('('); diff --git a/packages/abi/src/util/slice.spec.ts b/packages/abi/src/util/slice.spec.ts index cab3b6b5..46e07eb1 100644 --- a/packages/abi/src/util/slice.spec.ts +++ b/packages/abi/src/util/slice.spec.ts @@ -24,6 +24,9 @@ describe('util/slice', () => { it('returns an array with the slices otherwise', () => { const sliced = sliceData(`${slice1}${slice2}`); + if (!sliced) { + throw new Error('No matches'); + } expect(sliced.length).toEqual(2); expect(sliced[0]).toEqual(slice1); @@ -32,6 +35,9 @@ describe('util/slice', () => { it('removes leading 0x when passed in', () => { const sliced = sliceData(`0x${slice1}${slice2}`); + if (!sliced) { + throw new Error('No matches'); + } expect(sliced.length).toEqual(2); expect(sliced[0]).toEqual(slice1); diff --git a/packages/abi/src/util/slice.ts b/packages/abi/src/util/slice.ts index 068df652..7ab3f743 100644 --- a/packages/abi/src/util/slice.ts +++ b/packages/abi/src/util/slice.ts @@ -10,7 +10,7 @@ import { padAddress } from './pad'; * * @param data - Data to slice. */ -export const sliceData = (data: string): string[] => { +export const sliceData = (data: string): string[] | null => { if (!data || !data.length) { return []; } From 4a961b9c336aa9e05d7b6feade6fa890e8ec7075 Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Thu, 22 Nov 2018 14:18:43 +0100 Subject: [PATCH 04/13] Fix ts in abi --- packages/abi/src/spec/interface.ts | 2 +- packages/abi/src/util/signature.ts | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/abi/src/spec/interface.ts b/packages/abi/src/spec/interface.ts index fd858bb9..a77ab8db 100644 --- a/packages/abi/src/spec/interface.ts +++ b/packages/abi/src/spec/interface.ts @@ -23,7 +23,7 @@ class Interface { return new Token( paramType.type, (value as TokenValue[]).map(entry => - createToken(paramType.subtype, entry) + createToken(paramType.subtype as ParamType, entry) ) ); } diff --git a/packages/abi/src/util/signature.ts b/packages/abi/src/util/signature.ts index e0f0c864..6fc368fe 100644 --- a/packages/abi/src/util/signature.ts +++ b/packages/abi/src/util/signature.ts @@ -43,12 +43,7 @@ export const methodSignature = ( * * @param name - Name to parse. */ -export const parseName = ( - name: string | undefined -): { - strName: string; - name: string; -} => { +export const parseName = (name: string | undefined) => { const strName = `${name || ''}`; const index = strName.indexOf('('); From c0d7d86c1a98eab23ec0a024a2448974182e646e Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Thu, 22 Nov 2018 14:20:46 +0100 Subject: [PATCH 05/13] Fix ts in contracts --- jest.config.js | 2 +- packages/contracts/src/badgereg.ts | 20 +++++++++++--------- packages/contracts/src/contracts.ts | 18 +++++++++--------- packages/contracts/src/dappreg.ts | 20 ++++++++++---------- packages/contracts/src/githubhint.spec.ts | 2 +- packages/contracts/src/githubhint.ts | 8 ++++---- packages/contracts/src/registry.spec.ts | 2 +- packages/contracts/src/registry.ts | 20 ++++++++++---------- packages/contracts/src/signaturereg.ts | 6 +++--- packages/contracts/src/tokenreg.ts | 10 +++++----- 10 files changed, 55 insertions(+), 53 deletions(-) diff --git a/jest.config.js b/jest.config.js index b9bcebdb..17fd727b 100644 --- a/jest.config.js +++ b/jest.config.js @@ -11,5 +11,5 @@ module.exports = { '^.+\\.tsx?$': 'ts-jest' }, // testRegex: 'spec\\.(ts|tsx)$' // TODO Skip api/ tests for now, as it's still WIP - testRegex: `packages/(abi|electron|light\.js|light\.js-react)/.*spec\\.(ts|tsx)$` + testRegex: `packages/(abi|contracts|electron|light\.js|light\.js-react)/.*spec\\.(ts|tsx)$` }; diff --git a/packages/contracts/src/badgereg.ts b/packages/contracts/src/badgereg.ts index a92116fa..d2392e82 100644 --- a/packages/contracts/src/badgereg.ts +++ b/packages/contracts/src/badgereg.ts @@ -27,21 +27,21 @@ export default class BadgeReg { public certifiers: Metadata[] = []; public contracts: { [key: string]: Contract; - }; + } = {}; private _registry: Registry; - constructor(api: Api, registry: Registry) { + constructor (api: Api, registry: Registry) { this._api = api; this._registry = registry; registry.getContract('badgereg'); } - getContract() { + getContract () { return this._registry.getContract('badgereg'); } - certifierCount() { + certifierCount () { return this.getContract().then((badgeReg: Contract) => { return badgeReg.instance.badgeCount .call({}, []) @@ -49,7 +49,7 @@ export default class BadgeReg { }); } - fetchCertifier(id: number) { + fetchCertifier (id: number) { if (this.certifiers[id]) { return Promise.resolve(this.certifiers[id]); } @@ -75,7 +75,7 @@ export default class BadgeReg { }); } - fetchCertifierByName(name: string) { + fetchCertifierByName (name: string) { return this.getContract() .then((badgeReg: Contract) => { return badgeReg.instance.fromName.call({}, [name]); @@ -94,7 +94,7 @@ export default class BadgeReg { }); } - fetchMeta(id: number) { + fetchMeta (id: number) { return this.getContract() .then((badgeReg: Contract) => { return Promise.all([ @@ -106,15 +106,17 @@ export default class BadgeReg { title = bytesToHex(title).replace(/(00)+$/, ''); title = title === ZERO32 ? null : hexToAscii(title); + let resultIcon: string | null = icon; + if (bytesToHex(icon) === ZERO32) { - icon = null; + resultIcon = null; } return { title, icon }; }); } - checkIfCertified(certifier: string, address: string) { + checkIfCertified (certifier: string, address: string) { if (!this.contracts[certifier]) { this.contracts[certifier] = this._api.newContract(ABI, certifier); } diff --git a/packages/contracts/src/contracts.ts b/packages/contracts/src/contracts.ts index 9811042d..61e536db 100644 --- a/packages/contracts/src/contracts.ts +++ b/packages/contracts/src/contracts.ts @@ -11,7 +11,7 @@ import TokenReg from './tokenreg'; import GithubHint from './githubhint'; import BadgeReg from './badgereg'; -let instance: Contracts = null; +let instance: Contracts | undefined; export default class Contracts { private _api: Api; @@ -22,7 +22,7 @@ export default class Contracts { private _signaturereg: SignatureReg; private _tokenreg: TokenReg; - constructor(api: Api) { + constructor (api: Api) { instance = this; this._api = api; @@ -34,31 +34,31 @@ export default class Contracts { this._badgeReg = new BadgeReg(api, this._registry); } - get registry() { + get registry () { return this._registry; } - get badgeReg() { + get badgeReg () { return this._badgeReg; } - get dappReg() { + get dappReg () { return this._dappreg; } - get signatureReg() { + get signatureReg () { return this._signaturereg; } - get tokenReg() { + get tokenReg () { return this._tokenreg; } - get githubHint() { + get githubHint () { return this._githubhint; } - static get(api: Api) { + static get (api: Api) { if (!instance) { instance = new Contracts(api); } diff --git a/packages/contracts/src/dappreg.ts b/packages/contracts/src/dappreg.ts index 95dc0632..39475fa1 100644 --- a/packages/contracts/src/dappreg.ts +++ b/packages/contracts/src/dappreg.ts @@ -10,54 +10,54 @@ export default class DappReg { private _api: Api; private _registry: Registry; - constructor(api: Api, registry: Registry) { + constructor (api: Api, registry: Registry) { this._api = api; this._registry = registry; this.getInstance(); } - getContract() { + getContract () { return this._registry.getContract('dappreg'); } - getInstance() { + getInstance () { return this.getContract().then((contract: Contract) => contract.instance); } - count() { + count () { return this.getInstance().then((instance: ContractInstance) => { return instance.count.call(); }); } - at(index: number) { + at (index: number) { return this.getInstance().then((instance: ContractInstance) => { return instance.at.call({}, [index]); }); } - get(id: string) { + get (id: string) { return this.getInstance().then((instance: ContractInstance) => { return instance.get.call({}, [id]); }); } - meta(id: string, key: string) { + meta (id: string, key: string) { return this.getInstance().then((instance: ContractInstance) => { return instance.meta.call({}, [id, key]); }); } - getImage(id: string) { + getImage (id: string) { return this.meta(id, 'IMG'); } - getContent(id: string) { + getContent (id: string) { return this.meta(id, 'CONTENT'); } - getManifest(id: string) { + getManifest (id: string) { return this.meta(id, 'MANIFEST'); } } diff --git a/packages/contracts/src/githubhint.spec.ts b/packages/contracts/src/githubhint.spec.ts index 61cb715a..74ebfbec 100644 --- a/packages/contracts/src/githubhint.spec.ts +++ b/packages/contracts/src/githubhint.spec.ts @@ -12,7 +12,7 @@ let githubHint: GithubHint; let instance: ContractInstance; let registry: Registry; -function create() { +function create () { instance = { __id: 'testInstance', entries: { diff --git a/packages/contracts/src/githubhint.ts b/packages/contracts/src/githubhint.ts index e0f91782..5dc159dc 100644 --- a/packages/contracts/src/githubhint.ts +++ b/packages/contracts/src/githubhint.ts @@ -11,18 +11,18 @@ export default class GithubHint { private _instance: ContractInstance = null; private _registry: Registry; - constructor(api: Api, registry: Registry) { + constructor (api: Api, registry: Registry) { this._api = api; this._registry = registry; this.getInstance(); } - getContract() { + getContract () { return this._registry.getContract('githubhint'); } - getInstance() { + getInstance () { if (this._instance) { return Promise.resolve(this._instance); } @@ -33,7 +33,7 @@ export default class GithubHint { }); } - getEntry(entryId: string) { + getEntry (entryId: string) { return this.getInstance().then((instance: ContractInstance) => { return instance.entries.call({}, [entryId]); }); diff --git a/packages/contracts/src/registry.spec.ts b/packages/contracts/src/registry.spec.ts index cb398d03..127244e9 100644 --- a/packages/contracts/src/registry.spec.ts +++ b/packages/contracts/src/registry.spec.ts @@ -15,7 +15,7 @@ let api: Api; let instance: ContractInstance; let registry: Registry; -function create() { +function create () { instance = { __id: 'testInstance', get: { diff --git a/packages/contracts/src/registry.ts b/packages/contracts/src/registry.ts index 3ed7f922..5e2421fc 100644 --- a/packages/contracts/src/registry.ts +++ b/packages/contracts/src/registry.ts @@ -7,7 +7,7 @@ import * as abis from './abi'; import { Api, Contract, ContractInstance } from './types'; interface QueueItem { - resolve(...args: any[]): void; + resolve (...args: any[]): void; } const REGISTRY_V1_HASHES = [ @@ -26,15 +26,15 @@ export default class Registry { [key: string]: Promise; } = {}; private _queue: QueueItem[] = []; - private _registryContract: Contract = null; + private _registryContract: Contract | null = null; - constructor(api: Api) { + constructor (api: Api) { this._api = api; this.getInstance(); } - getInstance() { + getInstance () { if (this._instance) { return Promise.resolve(this._instance); } @@ -61,7 +61,7 @@ export default class Registry { }); } - getContract(_name: string) { + getContract (_name: string) { const name = _name.toLowerCase(); if (this._contracts[name]) { @@ -86,13 +86,13 @@ export default class Registry { return promise; } - getContractInstance(_name: string) { + getContractInstance (_name: string) { return this.getContract(_name).then( (contract: Contract) => contract.instance ); } - fetchContract() { + fetchContract () { if (this._registryContract) { return Promise.resolve(this._registryContract); } @@ -133,14 +133,14 @@ export default class Registry { }); } - _createGetParams(_name: string, key: string) { + _createGetParams (_name: string, key: string) { const name = _name.toLowerCase(); const sha3 = this._api.util.sha3.text(name); return [sha3, key]; } - lookupAddress(name: string) { + lookupAddress (name: string) { return this.getInstance() .then((instance: ContractInstance) => { return instance.getAddress.call({}, this._createGetParams(name, 'A')); @@ -151,7 +151,7 @@ export default class Registry { }); } - lookupMeta(name: string, key: string) { + lookupMeta (name: string, key: string) { return this.getInstance().then((instance: ContractInstance) => { return instance.get.call({}, this._createGetParams(name, key)); }); diff --git a/packages/contracts/src/signaturereg.ts b/packages/contracts/src/signaturereg.ts index 5594b4a2..4174b4c8 100644 --- a/packages/contracts/src/signaturereg.ts +++ b/packages/contracts/src/signaturereg.ts @@ -10,18 +10,18 @@ export default class SignatureReg { private _api: Api; private _registry: Registry; - constructor(api: Api, registry: Registry) { + constructor (api: Api, registry: Registry) { this._api = api; this._registry = registry; this.getInstance(); } - getInstance() { + getInstance () { return this._registry.getContractInstance('signaturereg'); } - lookup(signature: string) { + lookup (signature: string) { return this.getInstance().then((instance: ContractInstance) => { return instance.entries.call({}, [signature]); }); diff --git a/packages/contracts/src/tokenreg.ts b/packages/contracts/src/tokenreg.ts index 211678f2..a9020c41 100644 --- a/packages/contracts/src/tokenreg.ts +++ b/packages/contracts/src/tokenreg.ts @@ -10,28 +10,28 @@ export default class TokenReg { private _api: Api; private _registry: Registry; - constructor(api: Api, registry: Registry) { + constructor (api: Api, registry: Registry) { this._api = api; this._registry = registry; this.getInstance(); } - getContract() { + getContract () { return this._registry.getContract('tokenreg'); } - getInstance() { + getInstance () { return this.getContract().then((contract: Contract) => contract.instance); } - tokenCount() { + tokenCount () { return this.getInstance().then((instance: ContractInstance) => { return instance.tokenCount.call(); }); } - token(index: number) { + token (index: number) { return this.getInstance().then((instance: ContractInstance) => { return instance.token.call({}, [index]); }); From 45e06efb00fbe2ae60caae2890f53ac563efcf8b Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Thu, 22 Nov 2018 14:26:50 +0100 Subject: [PATCH 06/13] Fix lint in electron --- packages/electron/src/getParityPath.ts | 8 +++++--- packages/electron/src/index.ts | 2 +- packages/electron/src/isParityRunning.ts | 14 ++++++++------ packages/electron/src/runParity.ts | 9 ++++----- packages/electron/src/signerNewToken.ts | 2 +- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/packages/electron/src/getParityPath.ts b/packages/electron/src/getParityPath.ts index 5e4ae2b0..fb3875df 100644 --- a/packages/electron/src/getParityPath.ts +++ b/packages/electron/src/getParityPath.ts @@ -20,7 +20,7 @@ const fsStat = promisify(stat); * The default path to install parity, in case there's no other instance found * on the machine. */ -export function defaultParityPath() { +export function defaultParityPath () { return Promise.resolve( `${app.getPath('userData')}/parity${ process.platform === 'win32' ? '.exe' : '' @@ -33,7 +33,7 @@ export function defaultParityPath() { * * @ignore */ -let parityPath: string; +let parityPath: string | undefined; /** * Test if `parity` command is in $PATH. @@ -45,6 +45,8 @@ const isParityInPath = async () => { if (parityCommandExists) { // If yes, return `parity` as command to launch parity return 'parity'; + } else { + throw new Error('Parity not in path.'); } }; @@ -101,7 +103,7 @@ const doesParityExist = () => /** * Returns the path to Parity, or throws if parity is not found. */ -export async function getParityPath() { +export async function getParityPath () { if (parityPath) { return parityPath; } diff --git a/packages/electron/src/index.ts b/packages/electron/src/index.ts index e779d5d7..1fbdab9c 100644 --- a/packages/electron/src/index.ts +++ b/packages/electron/src/index.ts @@ -22,7 +22,7 @@ interface ParityElectronOptions { * Set default options for @parity/electron. Can be skipped if we don't want to * override default options. */ -function parityElectron(options: ParityElectronOptions = { logger: debug }) { +function parityElectron (options: ParityElectronOptions = { logger: debug }) { if (options.logger) { setLogger(options.logger); } diff --git a/packages/electron/src/isParityRunning.ts b/packages/electron/src/isParityRunning.ts index 97465a63..51eb3930 100644 --- a/packages/electron/src/isParityRunning.ts +++ b/packages/electron/src/isParityRunning.ts @@ -18,7 +18,7 @@ interface IsParityRunningOptions { * Detect if another instance of parity is already running or not. To achieve * that, we just ping on the common hosts. */ -export async function isParityRunning( +export async function isParityRunning ( options: IsParityRunningOptions = { wsInterface: '127.0.0.1', wsPort: '8546' @@ -43,15 +43,17 @@ export async function isParityRunning( setTimeout(() => resolve(false), TIMEOUT_MS); hostsToPing.map(host => - axios.get(host) + axios + .get(host) .then(_ => { logger()('@parity/electron:main')( `Another instance of parity is already running on ${host}, skip running local instance.` ); - resolve(true) + resolve(true); + }) + .catch(() => { + return null; }) - .catch(() => { return null; }) ); - - }) + }); } diff --git a/packages/electron/src/runParity.ts b/packages/electron/src/runParity.ts index eef91d55..b6a6bada 100644 --- a/packages/electron/src/runParity.ts +++ b/packages/electron/src/runParity.ts @@ -24,7 +24,7 @@ const fsChmod = promisify(chmod); /** * @ignore */ -let parity: ChildProcess = null; // Will hold the running parity instance +let parity: ChildProcess | null = null; // Will hold the running parity instance /** * These are errors output by parity, which we should ignore (i.e. don't @@ -41,7 +41,7 @@ const catchableErrors = [ /** * Spawns a child process to run Parity. */ -export async function runParity( +export async function runParity ( options: RunParityOptions = { flags: [], onParityError: () => { @@ -68,7 +68,6 @@ export async function runParity( } return new Promise((resolve, reject) => { - let logLastLine = ''; // Always contains last line of the Parity logs // Run an instance of parity with the correct flags @@ -119,7 +118,7 @@ export async function runParity( // Otherwise, if the exit code is not 0, then we show some error message onParityError(new Error(`Exit code ${exitCode}, with signal ${signal}.`)); }); - }) + }); } /** @@ -127,7 +126,7 @@ export async function runParity( * process. However, there's no guarantee that Parity has been cleanly killed, * and the Promise resolves instantly. */ -export function killParity() { +export function killParity () { if (parity) { logger()('Stopping parity.'); parity.kill(); diff --git a/packages/electron/src/signerNewToken.ts b/packages/electron/src/signerNewToken.ts index 4580958a..c2735f84 100644 --- a/packages/electron/src/signerNewToken.ts +++ b/packages/electron/src/signerNewToken.ts @@ -13,7 +13,7 @@ import logger from './utils/logger'; * Runs parity signer new-token and resolves with a new secure token to be * used in a dapp. Rejects if no token could be extracted. */ -export function signerNewToken(): Promise { +export function signerNewToken (): Promise { return new Promise(async (resolve, reject) => { logger()('@parity/electron:main')('Requesting new token.'); From de8eedd8220dc7c39165920a5db990a07c236a1c Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Thu, 22 Nov 2018 14:37:17 +0100 Subject: [PATCH 07/13] Fix lint in electron --- packages/electron/src/checkClockSync.ts | 2 +- packages/electron/src/fetchParity.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/electron/src/checkClockSync.ts b/packages/electron/src/checkClockSync.ts index 88def7a5..e714ae74 100644 --- a/packages/electron/src/checkClockSync.ts +++ b/packages/electron/src/checkClockSync.ts @@ -18,7 +18,7 @@ export const MAX_TIME_DRIFT = 10000; // milliseconds /** * Use SNTP to check if the local clock is synchronized; return the time drift. */ -export async function checkClockSync(): Promise { +export async function checkClockSync (): Promise { const { t: timeDrift }: { t: number } = await time(); return { isClockSync: timeDrift < MAX_TIME_DRIFT, diff --git a/packages/electron/src/fetchParity.ts b/packages/electron/src/fetchParity.ts index b3c539c0..f24be9d8 100644 --- a/packages/electron/src/fetchParity.ts +++ b/packages/electron/src/fetchParity.ts @@ -81,7 +81,7 @@ const getOs = () => { /** * Remove parity binary or partial binary in the userData folder, if it exists. */ -export async function deleteParity() { +export async function deleteParity () { const parityPath = await defaultParityPath(); // Remove parity binary @@ -103,7 +103,7 @@ export async function deleteParity() { * Downloads Parity, saves it to Electron's `userData` folder, and returns the * path to the downloaded binary once finished. */ -export async function fetchParity( +export async function fetchParity ( mainWindow: BrowserWindow, options: FetchParityOptions = { onProgress: () => { From ddafdf6fe20533e9fdd5b6bd94803950bdc00df3 Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Thu, 22 Nov 2018 14:41:53 +0100 Subject: [PATCH 08/13] Fix ts in light.js --- packages/light.js/src/frequency/accounts.ts | 4 ++-- packages/light.js/src/frequency/blocks.ts | 4 ++-- packages/light.js/src/frequency/health.ts | 2 +- packages/light.js/src/frequency/other.ts | 2 +- packages/light.js/src/frequency/time.ts | 6 +++--- .../utils/createPubsubObservable.spec.ts | 4 ++-- packages/light.js/src/rpc/eth.ts | 12 ++++++------ packages/light.js/src/rpc/net.ts | 2 +- packages/light.js/src/rpc/other/makeContract.ts | 2 +- packages/light.js/src/rpc/other/post.ts | 2 +- packages/light.js/src/rpc/parity.ts | 4 ++-- packages/light.js/src/types.ts | 2 +- packages/light.js/src/utils/isLoading.ts | 4 ++-- .../src/utils/operators/switchMapPromise.spec.ts | 4 ++-- .../src/utils/operators/switchMapPromise.ts | 2 +- .../light.js/src/utils/testHelpers/mockApi.ts | 16 ++++++++-------- 16 files changed, 36 insertions(+), 36 deletions(-) diff --git a/packages/light.js/src/frequency/accounts.ts b/packages/light.js/src/frequency/accounts.ts index 3b4b22bb..e92e15a2 100644 --- a/packages/light.js/src/frequency/accounts.ts +++ b/packages/light.js/src/frequency/accounts.ts @@ -11,7 +11,7 @@ import createPubsubObservable from './utils/createPubsubObservable'; * * @param options - Options to pass to {@link FrequencyObservable}. */ -export function onAccountsChanged$(options?: FrequencyObservableOptions) { +export function onAccountsChanged$ (options?: FrequencyObservableOptions) { return createPubsubObservable('eth_accounts', options); } @@ -20,6 +20,6 @@ export function onAccountsChanged$(options?: FrequencyObservableOptions) { * * @param options - Options to pass to {@link FrequencyObservable}. */ -export function onAccountsInfoChanged$(options?: FrequencyObservableOptions) { +export function onAccountsInfoChanged$ (options?: FrequencyObservableOptions) { return createPubsubObservable('parity_accountsInfo', options); } diff --git a/packages/light.js/src/frequency/blocks.ts b/packages/light.js/src/frequency/blocks.ts index 5fbe7e02..11b2fe53 100644 --- a/packages/light.js/src/frequency/blocks.ts +++ b/packages/light.js/src/frequency/blocks.ts @@ -19,7 +19,7 @@ import { onSyncingChanged$ } from './health'; * @ignore */ const onEveryBlockWithApi$ = memoizee( - (api: any, options: FrequencyObservableOptions) => + (api: any, options?: FrequencyObservableOptions) => createPubsubObservable('eth_blockNumber', options).pipe( withLatestFrom(onSyncingChanged$(options)), filter(([_, isSyncing]) => isSyncing === false), @@ -34,7 +34,7 @@ const onEveryBlockWithApi$ = memoizee( * * @param options - Options to pass to {@link FrequencyObservable}. */ -export function onEveryBlock$(options?: FrequencyObservableOptions) { +export function onEveryBlock$ (options?: FrequencyObservableOptions) { const api = options && options.provider ? createApiFromProvider(options.provider) diff --git a/packages/light.js/src/frequency/health.ts b/packages/light.js/src/frequency/health.ts index 3b4efb6e..4c6d424e 100644 --- a/packages/light.js/src/frequency/health.ts +++ b/packages/light.js/src/frequency/health.ts @@ -16,6 +16,6 @@ import { FrequencyObservableOptions } from '../types'; * * @param options - Options to pass to {@link FrequencyObservable}. */ -export function onSyncingChanged$(options?: FrequencyObservableOptions) { +export function onSyncingChanged$ (options?: FrequencyObservableOptions) { return createPubsubObservable('eth_syncing', options); } diff --git a/packages/light.js/src/frequency/other.ts b/packages/light.js/src/frequency/other.ts index 17ba97cd..276c60dc 100644 --- a/packages/light.js/src/frequency/other.ts +++ b/packages/light.js/src/frequency/other.ts @@ -13,7 +13,7 @@ import { FrequencyObservableOptions } from '../types'; * * @param options - Options to pass to {@link FrequencyObservable}. */ -function onStartup$(options?: FrequencyObservableOptions) { +function onStartup$ (options?: FrequencyObservableOptions) { return of(0); } // @ts-ignore diff --git a/packages/light.js/src/frequency/time.ts b/packages/light.js/src/frequency/time.ts index 217bdb5a..9767e38e 100644 --- a/packages/light.js/src/frequency/time.ts +++ b/packages/light.js/src/frequency/time.ts @@ -11,7 +11,7 @@ import { FrequencyObservableOptions } from '../types'; /** * Observable that emits on every second. */ -function onEverySecond$(options?: FrequencyObservableOptions) { +function onEverySecond$ (options?: FrequencyObservableOptions) { return timer(0, 1000); } // @ts-ignore @@ -20,7 +20,7 @@ onEverySecond$ = memoizee(onEverySecond$); /** * Observable that emits on every other second. */ -function onEvery2Seconds$(options?: FrequencyObservableOptions) { +function onEvery2Seconds$ (options?: FrequencyObservableOptions) { return timer(0, 2000); } // @ts-ignore @@ -29,7 +29,7 @@ onEvery2Seconds$ = memoizee(onEvery2Seconds$); /** * Observable that emits every five seconds. */ -function onEvery5Seconds$(options?: FrequencyObservableOptions) { +function onEvery5Seconds$ (options?: FrequencyObservableOptions) { return timer(0, 5000); } // @ts-ignore diff --git a/packages/light.js/src/frequency/utils/createPubsubObservable.spec.ts b/packages/light.js/src/frequency/utils/createPubsubObservable.spec.ts index f1dcb3d9..a52ba4ca 100644 --- a/packages/light.js/src/frequency/utils/createPubsubObservable.spec.ts +++ b/packages/light.js/src/frequency/utils/createPubsubObservable.spec.ts @@ -23,7 +23,7 @@ it('should fire an event when pubsub publishes', done => { it('should fire an error when pubsub errors', done => { setApi(rejectApi()); - createPubsubObservable('fake_method').subscribe(null, err => { + createPubsubObservable('fake_method').subscribe(undefined, err => { expect(err).toEqual(new Error('bar')); done(); }); @@ -47,7 +47,7 @@ it('should fire an event when polling pubsub publishes, with object', done => { it('should fire an error when polling pubsub errors', done => { setApi(rejectApi(new Error('bar'), false)); - createPubsubObservable('fake_method').subscribe(null, err => { + createPubsubObservable('fake_method').subscribe(undefined, err => { expect(err).toEqual(new Error('bar')); done(); }); diff --git a/packages/light.js/src/rpc/eth.ts b/packages/light.js/src/rpc/eth.ts index a5e190a1..6e6205ae 100644 --- a/packages/light.js/src/rpc/eth.ts +++ b/packages/light.js/src/rpc/eth.ts @@ -22,7 +22,7 @@ import { switchMapPromise } from '../utils/operators'; * @param options - Options to pass to {@link RpcObservableOptions}. * @return - An Observable containing the list of public addresses. */ -export function accounts$(options?: RpcObservableOptions) { +export function accounts$ (options?: RpcObservableOptions) { return createRpc$({ frequency: [frequency.onAccountsChanged$], name: 'accounts$' @@ -36,7 +36,7 @@ export function accounts$(options?: RpcObservableOptions) { * @param options - Options to pass to {@link RpcObservableOptions}. * @return - An Observable containing the balance. */ -export function balanceOf$(address: Address, options?: RpcObservableOptions) { +export function balanceOf$ (address: Address, options?: RpcObservableOptions) { return createRpc$({ calls: ['eth_getBalance'], frequency: [frequency.onEveryBlock$, frequency.onStartup$], @@ -52,7 +52,7 @@ export function balanceOf$(address: Address, options?: RpcObservableOptions) { * @return - An Observable containing the public address * of the default account. */ -export function defaultAccount$(options?: RpcObservableOptions) { +export function defaultAccount$ (options?: RpcObservableOptions) { return createRpc$({ dependsOn: accounts$, name: 'defaultAccount$', @@ -65,7 +65,7 @@ export function defaultAccount$(options?: RpcObservableOptions) { * * @return {Observable} - An Observable containing the block height. */ -export function blockNumber$(options?: RpcObservableOptions) { +export function blockNumber$ (options?: RpcObservableOptions) { return createRpc$({ frequency: [frequency.onEveryBlock$], name: 'blockNumber$' @@ -75,7 +75,7 @@ export function blockNumber$(options?: RpcObservableOptions) { /** * Shorthand for fetching the current account's balance. */ -export function myBalance$(options?: RpcObservableOptions) { +export function myBalance$ (options?: RpcObservableOptions) { return createRpc$({ calls: [`eth_getBalance`], dependsOn: defaultAccount$, @@ -96,7 +96,7 @@ export function myBalance$(options?: RpcObservableOptions) { * * @return - An Observable containing the syncing state object, or false. */ -export function syncStatus$(options?: RpcObservableOptions) { +export function syncStatus$ (options?: RpcObservableOptions) { return createRpc$({ frequency: [frequency.onSyncingChanged$], name: 'syncStatus$' diff --git a/packages/light.js/src/rpc/net.ts b/packages/light.js/src/rpc/net.ts index b67c5436..84b780c0 100644 --- a/packages/light.js/src/rpc/net.ts +++ b/packages/light.js/src/rpc/net.ts @@ -18,7 +18,7 @@ import { switchMapPromise } from '../utils/operators'; * @param options - Options to pass to {@link RpcObservableOptions}. * @return - An Observable containing the number. */ -export function peerCount$(options?: RpcObservableOptions) { +export function peerCount$ (options?: RpcObservableOptions) { return createRpc$({ calls: ['net_peerCount'], frequency: [frequency.onEvery5Seconds$], diff --git a/packages/light.js/src/rpc/other/makeContract.ts b/packages/light.js/src/rpc/other/makeContract.ts index 65e6fa80..00dcc9d9 100644 --- a/packages/light.js/src/rpc/other/makeContract.ts +++ b/packages/light.js/src/rpc/other/makeContract.ts @@ -58,7 +58,7 @@ const makeContractWithApi = memoizee( const result: MakeContract = { abi, address, - get contractObject() { + get contractObject () { return getContract(address, abiJson, api); } }; diff --git a/packages/light.js/src/rpc/other/post.ts b/packages/light.js/src/rpc/other/post.ts index 777eecca..6d5a0281 100644 --- a/packages/light.js/src/rpc/other/post.ts +++ b/packages/light.js/src/rpc/other/post.ts @@ -25,7 +25,7 @@ interface PostOptions extends RpcObservableOptions { * @param options? - Options to pass to the {@link RpcObservable}. * @return - The status of the transaction. */ -export function post$(tx: Tx, options: PostOptions = {}) { +export function post$ (tx: Tx, options: PostOptions = {}) { const { estimate, provider } = options; const api = provider ? createApiFromProvider(provider) : getApi(); diff --git a/packages/light.js/src/rpc/parity.ts b/packages/light.js/src/rpc/parity.ts index a8158aa0..930c1ea1 100644 --- a/packages/light.js/src/rpc/parity.ts +++ b/packages/light.js/src/rpc/parity.ts @@ -15,7 +15,7 @@ import { switchMapPromise } from '../utils/operators'; * @return - An Observable containing all info that can be * accessed by user concerning accounts. */ -export function accountsInfo$(options?: RpcObservableOptions) { +export function accountsInfo$ (options?: RpcObservableOptions) { return createRpc$({ frequency: [frequency.onAccountsInfoChanged$], name: 'accountsInfo$' @@ -29,7 +29,7 @@ export function accountsInfo$(options?: RpcObservableOptions) { * @return - An Observable containing the name of the * current chain. */ -export function chainName$(options?: RpcObservableOptions) { +export function chainName$ (options?: RpcObservableOptions) { return createRpc$({ calls: ['parity_chain'], frequency: [frequency.onStartup$], diff --git a/packages/light.js/src/types.ts b/packages/light.js/src/types.ts index feeea5a3..9ed40090 100644 --- a/packages/light.js/src/types.ts +++ b/packages/light.js/src/types.ts @@ -63,7 +63,7 @@ export type RpcKey = keyof typeof rpc; export interface RpcObservable { (...args: any[]): Observable; metadata?: Metadata; - setFrequency?(frequency: FrequencyObservable[]): void; // post$, makeContract... don't have setFrequency + setFrequency? (frequency: FrequencyObservable[]): void; // post$, makeContract... don't have setFrequency } export type RpcMap = { [index in RpcKey]: RpcObservable }; diff --git a/packages/light.js/src/utils/isLoading.ts b/packages/light.js/src/utils/isLoading.ts index c330c964..43be647c 100644 --- a/packages/light.js/src/utils/isLoading.ts +++ b/packages/light.js/src/utils/isLoading.ts @@ -11,7 +11,7 @@ export const RPC_LOADING = Symbol('Fetching RPC...'); * @param {Any} value - The value to test. * @return {Boolean} - Returns true if it's loading. */ -export function isLoading(value: any) { +export function isLoading (value: any) { return value === RPC_LOADING; } @@ -21,6 +21,6 @@ export function isLoading(value: any) { * @param {Any} value - The value to test. * @return {Boolean} - Returns true if it's `null, `undefined` or loading. */ -export function isNullOrLoading(value: any) { +export function isNullOrLoading (value: any) { return value == null || isLoading(value); } diff --git a/packages/light.js/src/utils/operators/switchMapPromise.spec.ts b/packages/light.js/src/utils/operators/switchMapPromise.spec.ts index 77046dda..d28d6ba8 100644 --- a/packages/light.js/src/utils/operators/switchMapPromise.spec.ts +++ b/packages/light.js/src/utils/operators/switchMapPromise.spec.ts @@ -13,7 +13,7 @@ import { switchMapPromise } from './switchMapPromise'; it('should not error when the promise resolves with an error', done => { mockRpc$() .pipe(switchMapPromise(resolveApi({ error: 'bar' }).fake.method)) - .subscribe(null, () => done.fail('It should not error.')); + .subscribe(undefined, () => done.fail('It should not error.')); // If after 0.1s, nothing has been called, then our Observable has not fired // any event, which is what we want @@ -23,7 +23,7 @@ it('should not error when the promise resolves with an error', done => { it('should not error when the promise rejects', done => { mockRpc$() .pipe(switchMapPromise(rejectApi().fake.method)) - .subscribe(null, () => done.fail('It should not error.')); + .subscribe(undefined, () => done.fail('It should not error.')); // If after 0.1s, nothing has been called, then our Observable has not fired // any event, which is what we want diff --git a/packages/light.js/src/utils/operators/switchMapPromise.ts b/packages/light.js/src/utils/operators/switchMapPromise.ts index f196be51..9a066fed 100644 --- a/packages/light.js/src/utils/operators/switchMapPromise.ts +++ b/packages/light.js/src/utils/operators/switchMapPromise.ts @@ -29,7 +29,7 @@ export const switchMapPromise = (promise: () => Promise) => ( return Promise.resolve(result); }) ).pipe( - startWith(RPC_LOADING), + startWith(RPC_LOADING as any), catchError(err => { console.group(); console.error({ call: promise.toString(), err }); diff --git a/packages/light.js/src/utils/testHelpers/mockApi.ts b/packages/light.js/src/utils/testHelpers/mockApi.ts index 4e8cbed7..430c788b 100644 --- a/packages/light.js/src/utils/testHelpers/mockApi.ts +++ b/packages/light.js/src/utils/testHelpers/mockApi.ts @@ -15,7 +15,7 @@ let providerCount = 0; * @ignore */ export class MockProvider extends EventEmitter { - send() { + send () { return Promise.resolve(); } } @@ -56,13 +56,13 @@ const createApi = ( listOfMockRps[namespace].forEach(method => { apiObject.pubsub[namespace][method] = isError ? (callback: Function) => { - callback(resolveWith, null); - return Promise.resolve(1); // Resolves to subscriptionId - } + callback(resolveWith, null); + return Promise.resolve(1); // Resolves to subscriptionId + } : (callback: Function) => { - callback(null, resolveWith); - return Promise.resolve(1); // Resolves to subscriptionId - }; + callback(null, resolveWith); + return Promise.resolve(1); // Resolves to subscriptionId + }; }); // For eth.syncing pubsub, always return false @@ -75,7 +75,7 @@ const createApi = ( }, { isPubSub, - pollMethod() { + pollMethod () { return isError ? Promise.reject(resolveWith) : Promise.resolve(resolveWith); From ebe4033ed561128cb71e87fa79d91bc59ec9fd0d Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Thu, 22 Nov 2018 14:41:59 +0100 Subject: [PATCH 09/13] Fix lint --- packages/api/src/transport/TransportError.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/api/src/transport/TransportError.ts b/packages/api/src/transport/TransportError.ts index 9aa3abee..9fe840ba 100644 --- a/packages/api/src/transport/TransportError.ts +++ b/packages/api/src/transport/TransportError.ts @@ -50,7 +50,7 @@ class TransportError extends Error { */ public type: string; - constructor(method: string, code: number, message: string) { + constructor (method: string, code: number, message: string) { const m = `${method}: ${code}: ${message}`; super(m); @@ -73,7 +73,7 @@ class TransportError extends Error { * * @param method - The method for which we create a `REQUEST_REJECTED` error. */ - static requestRejected(method: string = null) { + static requestRejected (method: string = null) { return new TransportError( method, ERROR_CODES.REQUEST_REJECTED, From add8558f7d1a2f72994adeb79560c20d64d41eab Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Thu, 22 Nov 2018 14:51:45 +0100 Subject: [PATCH 10/13] Fix bug in light.js, dependsOn and frequency --- packages/light.js/src/rpc/utils/createRpc.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/light.js/src/rpc/utils/createRpc.ts b/packages/light.js/src/rpc/utils/createRpc.ts index 82777b0c..0f25a5b8 100644 --- a/packages/light.js/src/rpc/utils/createRpc.ts +++ b/packages/light.js/src/rpc/utils/createRpc.ts @@ -10,7 +10,11 @@ import { merge, Observable, OperatorFunction } from 'rxjs'; import { createApiFromProvider, getApi } from '../../api'; import { distinctReplayRefCount } from '../../utils/operators'; -import { Metadata, RpcObservableOptions } from '../../types'; +import { + FrequencyObservable, + Metadata, + RpcObservableOptions +} from '../../types'; /** * Add metadata to an RpcObservable, and transform it into a ReplaySubject(1). @@ -25,12 +29,24 @@ import { Metadata, RpcObservableOptions } from '../../types'; */ const createRpcWithApi = memoizeeWeak( (api: any, metadata: Metadata, ...args: any[]) => { + if (!metadata.dependsOn && !metadata.frequency) { + throw new Error( + `Rpc$ '${ + metadata.name + }' needs either a 'dependsOn' or a 'frequency' field.` + ); + } + // The source Observable can either be another RpcObservable (in the // `dependsOn` field), or anObservable built by merging all the // FrequencyObservables const source$ = metadata.dependsOn ? metadata.dependsOn(...args, { provider: api.provider }) - : merge(...metadata.frequency.map(f => f({ provider: api.provider }))); + : merge( + ...(metadata.frequency as FrequencyObservable[]).map(f => + f({ provider: api.provider }) + ) + ); // The pipes to add const pipes: OperatorFunction[] = []; From d9475406eb8e03490d9a80b3ecf8158f6d488d80 Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Fri, 23 Nov 2018 12:17:33 +0100 Subject: [PATCH 11/13] encodeToken required argument --- packages/abi/src/encoder/encoder.spec.ts | 2 +- packages/abi/src/encoder/encoder.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/abi/src/encoder/encoder.spec.ts b/packages/abi/src/encoder/encoder.spec.ts index b2259efa..b3109e37 100644 --- a/packages/abi/src/encoder/encoder.spec.ts +++ b/packages/abi/src/encoder/encoder.spec.ts @@ -10,7 +10,7 @@ import { padAddress, padFixedBytes, padU32 } from '../util/pad'; describe('encoder/Encoder', () => { describe('encodeToken', () => { it('requires token as Token', () => { - expect(() => Encoder.encodeToken(undefined)).toThrow(/Token/); + expect(() => Encoder.encodeToken(undefined as any)).toThrow(/Token/); }); it('encodes address tokens in Mediate(raw)', () => { diff --git a/packages/abi/src/encoder/encoder.ts b/packages/abi/src/encoder/encoder.ts index 780f3233..f1cefb93 100644 --- a/packages/abi/src/encoder/encoder.ts +++ b/packages/abi/src/encoder/encoder.ts @@ -44,7 +44,7 @@ class Encoder { return `${inits}${closings}`; } - static encodeToken (token?: Token, index = 0): Mediate { + static encodeToken (token: Token, index = 0): Mediate { if (!token || !isInstanceOf(token, Token)) { throw new Error('token should be instanceof Token'); } From 0ec683581a9289290ba5b21f442e34b9849d2cb4 Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Fri, 23 Nov 2018 12:18:24 +0100 Subject: [PATCH 12/13] Fix bug resultIcon --- packages/contracts/src/badgereg.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/src/badgereg.ts b/packages/contracts/src/badgereg.ts index d2392e82..65e6616e 100644 --- a/packages/contracts/src/badgereg.ts +++ b/packages/contracts/src/badgereg.ts @@ -112,7 +112,7 @@ export default class BadgeReg { resultIcon = null; } - return { title, icon }; + return { title, icon: resultIcon }; }); } From 222a64cbb4189f6f423054bbeb6b91296a447769 Mon Sep 17 00:00:00 2001 From: Amaury Martiny Date: Fri, 23 Nov 2018 12:28:21 +0100 Subject: [PATCH 13/13] Encode required arg --- packages/abi/src/encoder/encoder.spec.ts | 2 +- packages/abi/src/encoder/encoder.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/abi/src/encoder/encoder.spec.ts b/packages/abi/src/encoder/encoder.spec.ts index b3109e37..d8f9a584 100644 --- a/packages/abi/src/encoder/encoder.spec.ts +++ b/packages/abi/src/encoder/encoder.spec.ts @@ -105,7 +105,7 @@ describe('encoder/Encoder', () => { describe('encode', () => { it('requires tokens array', () => { - expect(() => Encoder.encode(undefined)).toThrow(/array/); + expect(() => Encoder.encode(undefined as any)).toThrow(/array/); }); describe('addresses', () => { diff --git a/packages/abi/src/encoder/encoder.ts b/packages/abi/src/encoder/encoder.ts index f1cefb93..d769bc7e 100644 --- a/packages/abi/src/encoder/encoder.ts +++ b/packages/abi/src/encoder/encoder.ts @@ -24,7 +24,7 @@ import { } from '../types'; class Encoder { - static encode (tokens?: Token[]) { + static encode (tokens: Token[]) { if (!isArray(tokens)) { throw new Error('tokens should be array of Token'); }