Initial new UI source code import (#2607)

* address -> name mappings

* expanding, loading all coin details

* send use only actual BasicCoin tokens registered (any reg)

* sending token & accounts

* form styling updates

* send form layout in place

* coin send working as expected

* api subscriptions on multiple addresses

* bring in events

* simplify

* basic events display in-place, functionally complete

* basic functionality in-place

* fix horrible event address issue

* rwork display of events slightly

* test TLA availability

* table for owner -> tokens

* fix signature lookup address

* fix signature lookup address

* basic overview styling

* txhash links

* page layout adjustments

* background import

* adjust colors

* no global registration, simplify color selection

* updated styling

* connection dialog for "busy connecting"

* initial token connection - WIP

* init token updates take place

* basic test for manual token

* rework connection display

* allow updates of the secure token

* first stab at making the build build

* update runner tags

* fix linting issues

* skip tests requiring network (should be e2e, TODO)

* re-enable javascript tag/runner

* release push does the trick

* push to any branch, CI name

* javscript-test runner as well

* swap dependencies build requires test

* revert stages swap

* retrieve images associated with tokens

* remove js build deps order

* null image when hash = 0x0

* 6x64 images (hashes for registries)

* don't pass tokens as prop to IdentityIcon

* check images against content hash pictures

* cleanup signer after connection changes

* fix naming typo

* display unknownImages for balances (not available as content hash)

* unknownImage for transfer dialog

* basic githubhint layout

* single input for commit/filename

* ethcore_hashContent call

* lookup hash

* registration in place

* fixes

* events is using a proper table

* pass value through as-is

* stop wrongly using main app IdentityIcon

* NEVER export class instance functions

* alignment back to normal

* typo  in definition

* set & get images working (mostly)

* show content retrieval info

* set exitcode via ||

* use javascript:latest images

* disable npm progress bar

* rename phase I

* rename phase II

* only send build output to GitHub on major branches

* also run the build step as part of the test (until comprehensive)

* ci-specific build (no webpack progress)

* allow for account creation via recovery phrase

* display account uuid (where available), closes #2546

* connection dialog now shows up in dapps as well, closes #2538

* token images show up as expected

* IdentityName component added and deployed

* fix padding tests

* adjust tests to map to stricter 0x-prefixed hex

* render names via common component for the address -> name

* split lint into seperate script (early exit)

* test phases changed to lint, test & pack

* pack part of test phase

* remove files marked for deletion (cleanup)

* Signer cleanups, start moving in the direction of the rest

* add personal signer methods

* basic signer request subscription

* don't poll blockNumber when not connected

* missing return, creating massive ws queue backlogs

* ΞTH -> ETH

* fix failing tests

* registry uses setAddress to actually set addresses now

* bytes mapping operates on lowerCase hex strings

* sha3 ids for each application

* add dappreg to list of contracts

* adjust alignment of queries

* show gas estimation log

* abi with payable for register function

* add key as required

* image retrieval from dappreg

* use proper Image urls

* embed and link apps from Parity, retrieved via /api/apps

* filter apps that has been replaced

* proxy entry for parity-utils

* add basiccoin abi

* add support for fallback abi type

* capture constructor paramaters

* merge master into js

* move images to assets/images/

* add font assets

* import fonts as part of build

* don't inline woff files

* Revert "merge master into js"

This reverts commit cfcfa81bd26f1b3cbc748d3afa1eb5c670b363fe.

* remove unused npm packages

* information on gas estimates (like almost everywhere else)

* don't pass gas & gasPrice to estimation

* display account passwordhint when available

* signer subscriptions based on polling & function trapping

* pending requests retrieved via jsapi

* update signer middleware

* remove all web3 instances

* remove web3 package

* last web3 dependencies removed

* no need to toChecksumAddress - api takes care of it

* expand description for personal_confirmRequest

* Signer conversion from web3 -> parity.js completed

* explicit in no return

* green circle background

* remove generated background

* convert /api/* paths to localhost:8080/api/* paths (hard-coded, temporary)

* change dapps to load from localhost:8080/ui/*

* remove dangling web3 files

* update manager test for signer

* /api/ping -> /

* additional token images

* additional token images

* add missing styles.css for 8180 error pages

* cater for txhash returning null/empty object

* adjust output directories

* Release merge with origin with ours strategy

* additional token images

* cater for development server

* s/localhost/127.0.0.1/ (cater for origin)

* Fix address selection for contract deployment

* Adjust z-index for error overlay

* better text on unique background pattern

* fix signer rejections

* Don't allow gavcoin transfer with no balance

* fix txhash rendering in signer

* remove unnecessary ParityBackground

* script to update js-precompiled

* Redirect from :8080 to :8180

* Remove extra return

* Dapp logo images
This commit is contained in:
Jaco Greeff
2016-10-18 11:52:56 +02:00
committed by Gav Wood
parent 6c7af57529
commit 1e6a2cb378
969 changed files with 57315 additions and 0 deletions

83
js/src/api/util/decode.js Normal file
View File

@@ -0,0 +1,83 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { isHex } from './types';
import Func from '../../abi/spec/function';
import { fromParamType, toParamType } from '../../abi/spec/paramType/format';
export function decodeCallData (data) {
if (!isHex(data)) {
throw new Error('Input to decodeCallData should be a hex value');
}
if (data.substr(0, 2) === '0x') {
return decodeCallData(data.slice(2));
} else if (data.length < 8) {
throw new Error('Input to decodeCallData should be method signature + data');
}
const signature = data.substr(0, 8);
const paramdata = data.substr(8);
return {
signature: `0x${signature}`,
paramdata: `0x${paramdata}`
};
}
export function decodeMethodInput (methodAbi, paramdata) {
if (!methodAbi) {
throw new Error('decodeMethodInput should receive valid method-specific ABI');
} else if (!paramdata) {
throw new Error('decodeMethodInput should receive valid parameter input data');
} else if (!isHex(paramdata)) {
throw new Error('Input to decodeMethodInput should be a hex value');
} else if (paramdata.substr(0, 2) === '0x') {
return decodeMethodInput(methodAbi, paramdata.slice(2));
} else if (paramdata.length % 64 !== 0) {
throw new Error('Parameter length in decodeMethodInput not a multiple of 64 characters');
}
return new Func(methodAbi).decodeInput(paramdata).map((decoded) => decoded.value);
}
// takes a method in form name(...,types) and returns the inferred abi definition
export function methodToAbi (method) {
const length = method.length;
const typesStart = method.indexOf('(');
const typesEnd = method.indexOf(')');
if (typesStart === -1) {
throw new Error(`Missing start ( in call to decodeMethod with ${method}`);
} else if (typesEnd === -1) {
throw new Error(`Missing end ) in call to decodeMethod with ${method}`);
} else if (typesEnd < typesStart) {
throw new Error(`End ) is before start ( in call to decodeMethod with ${method}`);
} else if (typesEnd !== length - 1) {
throw new Error(`Extra characters after end ) in call to decodeMethod with ${method}`);
}
const name = method.substr(0, typesStart);
const types = method.substr(typesStart + 1, length - (typesStart + 1) - 1).split(',');
const inputs = types.map((_type) => {
const type = fromParamType(toParamType(_type));
return { type };
});
return { type: 'function', name, inputs };
}

View File

@@ -0,0 +1,101 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import BigNumber from 'bignumber.js';
import { decodeCallData, decodeMethodInput, methodToAbi } from './decode';
describe('api/util/decode', () => {
const METH = '0x70a08231';
const ENCO = '0x70a082310000000000000000000000005A5eFF38DA95b0D58b6C616f2699168B480953C9';
const DATA = '0x0000000000000000000000005A5eFF38DA95b0D58b6C616f2699168B480953C9';
describe('decodeCallData', () => {
it('throws on non-hex inputs', () => {
expect(() => decodeCallData('invalid')).to.throw(/should be a hex value/);
});
it('throws when invalid signature length', () => {
expect(() => decodeCallData(METH.slice(-6))).to.throw(/should be method signature/);
});
it('splits valid inputs properly', () => {
expect(decodeCallData(ENCO)).to.deep.equal({
signature: METH,
paramdata: DATA
});
});
});
describe('decodeMethodInput', () => {
it('expects a valid ABI', () => {
expect(() => decodeMethodInput(null, null)).to.throw(/should receive valid method/);
});
it('expects valid parameter data', () => {
expect(() => decodeMethodInput({}, null)).to.throw(/should receive valid parameter/);
});
it('expect valid hex parameter data', () => {
expect(() => decodeMethodInput({}, 'invalid')).to.throw(/should be a hex value/);
});
it('throws on invalid lengths', () => {
expect(() => decodeMethodInput({}, DATA.slice(-32))).to.throw(/not a multiple of/);
});
it('correctly decodes valid inputs', () => {
expect(decodeMethodInput({
type: 'function',
inputs: [
{ type: 'uint' }
]
}, DATA)).to.deep.equal([ new BigNumber('0x5a5eff38da95b0d58b6c616f2699168b480953c9') ]);
});
});
describe('methodToAbi', () => {
it('throws when no start ( specified', () => {
expect(() => methodToAbi('invalid,uint,bool)')).to.throw(/Missing start \(/);
});
it('throws when no end ) specified', () => {
expect(() => methodToAbi('invalid(uint,bool')).to.throw(/Missing end \)/);
});
it('throws when end ) is not in the last position', () => {
expect(() => methodToAbi('invalid(uint,bool)2')).to.throw(/Extra characters after end \)/);
});
it('throws when start ( is after end )', () => {
expect(() => methodToAbi('invalid)uint,bool(')).to.throw(/End \) is before start \(/);
});
it('throws when invalid types are present', () => {
expect(() => methodToAbi('method(invalidType,bool,uint)')).to.throw(/Cannot convert invalidType/);
});
it('returns a valid methodabi for a valid method', () => {
expect(methodToAbi('valid(uint,bool)')).to.deep.equals({
type: 'function',
name: 'valid',
inputs: [
{ type: 'uint256' },
{ type: 'bool' }
]
});
});
});
});

19
js/src/api/util/format.js Normal file
View File

@@ -0,0 +1,19 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
export function bytesToHex (bytes) {
return '0x' + bytes.map((b) => ('0' + b.toString(16)).slice(-2)).join('');
}

View File

@@ -0,0 +1,29 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { bytesToHex } from './format';
describe('api/util/format', () => {
describe('bytesToHex', () => {
it('correctly converts an empty array', () => {
expect(bytesToHex([])).to.equal('0x');
});
it('correctly converts a non-empty array', () => {
expect(bytesToHex([0, 15, 16])).to.equal('0x000f10');
});
});
});

View File

@@ -0,0 +1,9 @@
import blockies from 'blockies';
export function createIdentityImg (address, scale = 8) {
return blockies({
seed: (address || '').toLowerCase(),
size: 8,
scale
}).toDataURL();
}

41
js/src/api/util/index.js Normal file
View File

@@ -0,0 +1,41 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { isAddress as isAddressValid, toChecksumAddress } from '../../abi/util/address';
import { decodeCallData, decodeMethodInput, methodToAbi } from './decode';
import { bytesToHex } from './format';
import { fromWei, toWei } from './wei';
import { sha3 } from './sha3';
import { isArray, isFunction, isHex, isInstanceOf, isString } from './types';
import { createIdentityImg } from './identity';
export default {
isAddressValid,
isArray,
isFunction,
isHex,
isInstanceOf,
isString,
bytesToHex,
createIdentityImg,
decodeCallData,
decodeMethodInput,
methodToAbi,
fromWei,
toChecksumAddress,
toWei,
sha3
};

21
js/src/api/util/sha3.js Normal file
View File

@@ -0,0 +1,21 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { keccak_256 } from 'js-sha3'; // eslint-disable-line camelcase
export function sha3 (value) {
return `0x${keccak_256(value)}`;
}

View File

@@ -0,0 +1,25 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { sha3 } from './sha3';
describe('api/util/sha3', () => {
describe('sha3', () => {
it('constructs a correct sha3 value', () => {
expect(sha3('jacogr')).to.equal('0x2f4ff4b5a87abbd2edfed699db48a97744e028c7f7ce36444d40d29d792aa4dc');
});
});
});

56
js/src/api/util/types.js Normal file
View File

@@ -0,0 +1,56 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
const HEXDIGITS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
export function isArray (test) {
return Object.prototype.toString.call(test) === '[object Array]';
}
export function isError (test) {
return Object.prototype.toString.call(test) === '[object Error]';
}
export function isFunction (test) {
return Object.prototype.toString.call(test) === '[object Function]';
}
export function isHex (_test) {
if (_test.substr(0, 2) === '0x') {
return isHex(_test.slice(2));
}
const test = _test.toLowerCase();
let hex = true;
for (let idx = 0; hex && idx < test.length; idx++) {
hex = HEXDIGITS.includes(test[idx]);
}
return hex;
}
export function isObject (test) {
return Object.prototype.toString.call(test) === '[object Object]';
}
export function isString (test) {
return Object.prototype.toString.call(test) === '[object String]';
}
export function isInstanceOf (test, clazz) {
return test instanceof clazz;
}

View File

@@ -0,0 +1,112 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import sinon from 'sinon';
import { isArray, isError, isFunction, isHex, isInstanceOf, isObject, isString } from './types';
import Eth from '../rpc/eth';
describe('api/util/types', () => {
describe('isArray', () => {
it('correctly identifies null as false', () => {
expect(isArray(null)).to.be.false;
});
it('correctly identifies empty array as true', () => {
expect(isArray([])).to.be.true;
});
it('correctly identifies array as true', () => {
expect(isArray([1, 2, 3])).to.be.true;
});
});
describe('isError', () => {
it('correctly identifies null as false', () => {
expect(isError(null)).to.be.false;
});
it('correctly identifies Error as true', () => {
expect(isError(new Error('an error'))).to.be.true;
});
});
describe('isFunction', () => {
it('correctly identifies null as false', () => {
expect(isFunction(null)).to.be.false;
});
it('correctly identifies function as true', () => {
expect(isFunction(sinon.stub())).to.be.true;
});
});
describe('isHex', () => {
it('correctly identifies hex by leading 0x', () => {
expect(isHex('0x123')).to.be.true;
});
it('correctly identifies hex without leading 0x', () => {
expect(isHex('123')).to.be.true;
});
it('correctly identifies non-hex values', () => {
expect(isHex('123j')).to.be.false;
});
});
describe('isInstanceOf', () => {
it('correctly identifies build-in instanceof', () => {
expect(isInstanceOf(new String('123'), String)).to.be.true; // eslint-disable-line no-new-wrappers
});
it('correctly identifies own instanceof', () => {
expect(isInstanceOf(new Eth({}), Eth)).to.be.true;
});
it('correctly reports false for own', () => {
expect(isInstanceOf({}, Eth)).to.be.false;
});
});
describe('isObject', () => {
it('correctly identifies empty object as object', () => {
expect(isObject({})).to.be.true;
});
it('correctly identifies non-empty object as object', () => {
expect(isObject({ data: '123' })).to.be.true;
});
it('correctly identifies Arrays as non-objects', () => {
expect(isObject([1, 2, 3])).to.be.false;
});
it('correctly identifies Strings as non-objects', () => {
expect(isObject('123')).to.be.false;
});
});
describe('isString', () => {
it('correctly identifies empty string as string', () => {
expect(isString('')).to.be.true;
});
it('correctly identifies string as string', () => {
expect(isString('123')).to.be.true;
});
});
});

37
js/src/api/util/wei.js Normal file
View File

@@ -0,0 +1,37 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import BigNumber from 'bignumber.js';
const UNITS = ['wei', 'ada', 'babbage', 'shannon', 'szabo', 'finney', 'ether', 'kether', 'mether', 'gether', 'tether'];
export function _getUnitMultiplier (unit) {
const position = UNITS.indexOf(unit.toLowerCase());
if (position === -1) {
throw new Error(`Unknown unit ${unit} passed to wei formatter`);
}
return 10 ** (position * 3);
}
export function fromWei (value, unit = 'ether') {
return new BigNumber(value).div(_getUnitMultiplier(unit));
}
export function toWei (value, unit = 'ether') {
return new BigNumber(value).mul(_getUnitMultiplier(unit));
}

View File

@@ -0,0 +1,57 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import { _getUnitMultiplier, fromWei, toWei } from './wei';
describe('api/util/wei', () => {
describe('_getUnitMultiplier', () => {
it('returns 10^0 for wei', () => {
expect(_getUnitMultiplier('wei')).to.equal(10 ** 0);
});
it('returns 10^15 for finney', () => {
expect(_getUnitMultiplier('finney')).to.equal(10 ** 15);
});
it('returns 10^18 for ether', () => {
expect(_getUnitMultiplier('ether')).to.equal(10 ** 18);
});
it('throws an error on invalid units', () => {
expect(() => _getUnitMultiplier('invalid')).to.throw(/passed to wei formatter/);
});
});
describe('fromWei', () => {
it('formats into ether when nothing specified', () => {
expect(fromWei('1230000000000000000').toString()).to.equal('1.23');
});
it('formats into finney when specified', () => {
expect(fromWei('1230000000000000000', 'finney').toString()).to.equal('1230');
});
});
describe('toWei', () => {
it('formats from ether when nothing specified', () => {
expect(toWei(1.23).toString()).to.equal('1230000000000000000');
});
it('formats from finney when specified', () => {
expect(toWei(1230, 'finney').toString()).to.equal('1230000000000000000');
});
});
});