2018-03-05 18:58:53 +00:00
|
|
|
import qs from 'query-string';
|
2018-01-02 18:04:50 +00:00
|
|
|
import has from 'lodash/has';
|
2018-04-06 21:32:25 +00:00
|
|
|
import EthTx from 'ethereumjs-tx';
|
2018-04-25 03:29:34 +00:00
|
|
|
import semver from 'semver';
|
2018-04-06 21:08:28 +00:00
|
|
|
import { BlockExplorerConfig } from 'types/network';
|
2018-01-02 18:04:50 +00:00
|
|
|
|
2018-03-07 23:36:05 +00:00
|
|
|
interface IObjectValue {
|
|
|
|
[key: string]: any;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function objectContainsObjectKeys(
|
|
|
|
checkingObject: IObjectValue,
|
|
|
|
containingObject: IObjectValue
|
|
|
|
) {
|
2018-01-02 18:04:50 +00:00
|
|
|
const checkingObjectKeys = Object.keys(checkingObject);
|
|
|
|
const containsAll = checkingObjectKeys.map(key => has(containingObject, key));
|
|
|
|
return containsAll.every(isTrue => isTrue);
|
|
|
|
}
|
|
|
|
|
2018-03-07 23:36:05 +00:00
|
|
|
export function getKeyByValue(object: IObjectValue, value: any) {
|
2017-09-26 23:03:38 +00:00
|
|
|
return Object.keys(object).find(key => object[key] === value);
|
|
|
|
}
|
2017-10-11 05:04:49 +00:00
|
|
|
|
|
|
|
export function getParam(query: { [key: string]: string }, key: string) {
|
|
|
|
const keys = Object.keys(query);
|
|
|
|
const index = keys.findIndex(k => k.toLowerCase() === key.toLowerCase());
|
|
|
|
if (index === -1) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return query[keys[index]];
|
|
|
|
}
|
|
|
|
|
2018-03-05 18:58:53 +00:00
|
|
|
export function getParamFromURL(url: string, param: string): string | undefined {
|
|
|
|
return qs.parse(qs.extract(url))[param];
|
|
|
|
}
|
|
|
|
|
2017-10-11 05:04:49 +00:00
|
|
|
export function isPositiveInteger(n: number) {
|
|
|
|
return Number.isInteger(n) && n > 0;
|
|
|
|
}
|
2018-01-20 20:06:28 +00:00
|
|
|
|
2018-03-07 23:36:05 +00:00
|
|
|
export const getValues = (...args: any[]) =>
|
2018-01-20 20:06:28 +00:00
|
|
|
args.reduce((acc, currArg) => [...acc, ...Object.values(currArg)], []);
|
2018-04-06 21:08:28 +00:00
|
|
|
|
2018-04-06 21:32:25 +00:00
|
|
|
export function transactionToRLP(tx: EthTx): string {
|
|
|
|
const { v, r, s } = tx;
|
|
|
|
|
|
|
|
// Poor man's serialize without signature.
|
|
|
|
tx.v = Buffer.from([tx._chainId]);
|
|
|
|
tx.r = Buffer.from([0]);
|
|
|
|
tx.s = Buffer.from([0]);
|
|
|
|
|
|
|
|
const rlp = '0x' + tx.serialize().toString('hex');
|
|
|
|
|
|
|
|
// Restore previous values
|
|
|
|
tx.v = v;
|
|
|
|
tx.r = r;
|
|
|
|
tx.s = s;
|
|
|
|
|
|
|
|
return rlp;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function signTransactionWithSignature(tx: EthTx, signature: string): Buffer {
|
|
|
|
const sigBuf = Buffer.from(signature.substr(2), 'hex');
|
|
|
|
|
|
|
|
// Mimicking the way tx.sign() works
|
|
|
|
let v = sigBuf[64] + 27;
|
|
|
|
|
|
|
|
if (tx._chainId > 0) {
|
|
|
|
v += tx._chainId * 2 + 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
tx.r = sigBuf.slice(0, 32);
|
|
|
|
tx.s = sigBuf.slice(32, 64);
|
|
|
|
tx.v = Buffer.from([v]);
|
|
|
|
|
|
|
|
return tx.serialize();
|
|
|
|
}
|
|
|
|
|
2018-04-06 21:08:28 +00:00
|
|
|
interface ExplorerConfig {
|
|
|
|
name: string;
|
|
|
|
origin: string;
|
|
|
|
txPath?: string;
|
|
|
|
addressPath?: string;
|
|
|
|
blockPath?: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function makeExplorer(expConfig: ExplorerConfig): BlockExplorerConfig {
|
|
|
|
const config: ExplorerConfig = {
|
|
|
|
// Defaults
|
|
|
|
txPath: 'tx',
|
|
|
|
addressPath: 'address',
|
|
|
|
blockPath: 'block',
|
|
|
|
...expConfig
|
|
|
|
};
|
|
|
|
|
|
|
|
return {
|
|
|
|
name: config.name,
|
|
|
|
origin: config.origin,
|
|
|
|
txUrl: hash => `${config.origin}/${config.txPath}/${hash}`,
|
|
|
|
addressUrl: address => `${config.origin}/${config.addressPath}/${address}`,
|
|
|
|
blockUrl: blockNum => `${config.origin}/${config.blockPath}/${blockNum}`
|
|
|
|
};
|
|
|
|
}
|
2018-04-25 03:29:34 +00:00
|
|
|
|
|
|
|
export function isNewerVersion(oldVersion: string, newVersion: string) {
|
|
|
|
// 1.0.0 -> 1.0.1
|
|
|
|
if (semver.lt(oldVersion, newVersion)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 1.0.0-RC.0 -> 1.0.0-RC.1
|
|
|
|
// TODO: Remove this code once done with release candidates
|
|
|
|
const oldv = semver.coerce(oldVersion);
|
|
|
|
const newv = semver.coerce(newVersion);
|
|
|
|
if (oldv && newv && semver.eq(oldv, newv)) {
|
|
|
|
const oldRc = parseInt(oldVersion.split('-RC.')[1], 10);
|
|
|
|
const newRc = parseInt(newVersion.split('-RC.')[1], 10);
|
|
|
|
if (newRc > oldRc) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|