parent
8a6f7022ea
commit
53ceffaef4
@ -0,0 +1,386 @@ |
||||
// This file is ported from ether.js/src.ts/utils/bytes.ts
|
||||
|
||||
import * as errors from './errors'; |
||||
|
||||
export type Arrayish = string | ArrayLike<number>; |
||||
|
||||
export interface Hexable { |
||||
toHexString(): string; |
||||
} |
||||
|
||||
export interface Signature { |
||||
r: string; |
||||
s: string; |
||||
|
||||
/* At least one of the following MUST be specified; the other will be derived */ |
||||
recoveryParam?: number; |
||||
v?: number; |
||||
} |
||||
|
||||
///////////////////////////////
|
||||
|
||||
export function isHexable(value: any): value is Hexable { |
||||
return !!value.toHexString; |
||||
} |
||||
|
||||
function addSlice(array: Uint8Array): Uint8Array { |
||||
if (array.slice) { |
||||
return array; |
||||
} |
||||
|
||||
// tslint:disable-next-line: only-arrow-functions
|
||||
array.slice = function() { |
||||
const args = Array.prototype.slice.call(arguments); |
||||
return addSlice(new Uint8Array(Array.prototype.slice.apply(array, args))); |
||||
}; |
||||
|
||||
return array; |
||||
} |
||||
|
||||
export function isArrayish(value: any): value is Arrayish { |
||||
if ( |
||||
!value || |
||||
// tslint:disable-next-line: radix
|
||||
parseInt(String(value.length)) !== value.length || |
||||
typeof value === 'string' |
||||
) { |
||||
return false; |
||||
} |
||||
|
||||
// tslint:disable-next-line: prefer-for-of
|
||||
for (let i = 0; i < value.length; i++) { |
||||
const v = value[i]; |
||||
// tslint:disable-next-line: radix
|
||||
if (v < 0 || v >= 256 || parseInt(String(v)) !== v) { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
export function arrayify(value: Arrayish | Hexable): Uint8Array { |
||||
if (value == null) { |
||||
errors.throwError( |
||||
'cannot convert null value to array', |
||||
errors.INVALID_ARGUMENT, |
||||
{ arg: 'value', value }, |
||||
); |
||||
} |
||||
|
||||
if (isHexable(value)) { |
||||
value = value.toHexString(); |
||||
} |
||||
|
||||
if (typeof value === 'string') { |
||||
const match = value.match(/^(0x)?[0-9a-fA-F]*$/); |
||||
|
||||
if (!match) { |
||||
errors.throwError('invalid hexidecimal string', errors.INVALID_ARGUMENT, { |
||||
arg: 'value', |
||||
value, |
||||
}); |
||||
} |
||||
|
||||
if (match[1] !== '0x') { |
||||
errors.throwError( |
||||
'hex string must have 0x prefix', |
||||
errors.INVALID_ARGUMENT, |
||||
{ arg: 'value', value }, |
||||
); |
||||
} |
||||
|
||||
value = value.substring(2); |
||||
if (value.length % 2) { |
||||
value = '0' + value; |
||||
} |
||||
|
||||
const result = []; |
||||
for (let i = 0; i < value.length; i += 2) { |
||||
result.push(parseInt(value.substr(i, 2), 16)); |
||||
} |
||||
|
||||
return addSlice(new Uint8Array(result)); |
||||
} |
||||
|
||||
if (isArrayish(value)) { |
||||
return addSlice(new Uint8Array(value)); |
||||
} |
||||
|
||||
errors.throwError('invalid arrayify value', null, { |
||||
arg: 'value', |
||||
value, |
||||
type: typeof value, |
||||
}); |
||||
return null; |
||||
} |
||||
|
||||
export function concat(objects: Arrayish[]): Uint8Array { |
||||
const arrays = []; |
||||
let length = 0; |
||||
// tslint:disable-next-line: prefer-for-of
|
||||
for (let i = 0; i < objects.length; i++) { |
||||
const object = arrayify(objects[i]); |
||||
arrays.push(object); |
||||
length += object.length; |
||||
} |
||||
|
||||
const result = new Uint8Array(length); |
||||
let offset = 0; |
||||
// tslint:disable-next-line: prefer-for-of
|
||||
for (let i = 0; i < arrays.length; i++) { |
||||
result.set(arrays[i], offset); |
||||
offset += arrays[i].length; |
||||
} |
||||
|
||||
return addSlice(result); |
||||
} |
||||
|
||||
export function stripZeros(value: Arrayish): Uint8Array { |
||||
let result: Uint8Array = arrayify(value); |
||||
|
||||
if (result.length === 0) { |
||||
return result; |
||||
} |
||||
|
||||
// Find the first non-zero entry
|
||||
let start = 0; |
||||
while (result[start] === 0) { |
||||
start++; |
||||
} |
||||
|
||||
// If we started with zeros, strip them
|
||||
if (start) { |
||||
result = result.slice(start); |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
export function padZeros(value: Arrayish, length: number): Uint8Array { |
||||
value = arrayify(value); |
||||
|
||||
if (length < value.length) { |
||||
throw new Error('cannot pad'); |
||||
} |
||||
|
||||
const result = new Uint8Array(length); |
||||
result.set(value, length - value.length); |
||||
return addSlice(result); |
||||
} |
||||
|
||||
export function isHexString(value: any, length?: number): boolean { |
||||
if (typeof value !== 'string' || !value.match(/^0x[0-9A-Fa-f]*$/)) { |
||||
return false; |
||||
} |
||||
if (length && value.length !== 2 + 2 * length) { |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
const HexCharacters: string = '0123456789abcdef'; |
||||
|
||||
export function hexlify(value: Arrayish | Hexable | number): string { |
||||
if (isHexable(value)) { |
||||
return value.toHexString(); |
||||
} |
||||
|
||||
if (typeof value === 'number') { |
||||
if (value < 0) { |
||||
errors.throwError( |
||||
'cannot hexlify negative value', |
||||
errors.INVALID_ARGUMENT, |
||||
{ arg: 'value', value }, |
||||
); |
||||
} |
||||
|
||||
// @TODO: Roll this into the above error as a numeric fault (overflow); next version, not backward compatible
|
||||
// We can about (value == MAX_INT) to as well, since that may indicate we underflowed already
|
||||
if (value >= 9007199254740991) { |
||||
errors.throwError('out-of-range', errors.NUMERIC_FAULT, { |
||||
operartion: 'hexlify', |
||||
fault: 'out-of-safe-range', |
||||
}); |
||||
} |
||||
|
||||
let hex = ''; |
||||
while (value) { |
||||
hex = HexCharacters[value & 0x0f] + hex; |
||||
value = Math.floor(value / 16); |
||||
} |
||||
|
||||
if (hex.length) { |
||||
if (hex.length % 2) { |
||||
hex = '0' + hex; |
||||
} |
||||
return '0x' + hex; |
||||
} |
||||
|
||||
return '0x00'; |
||||
} |
||||
|
||||
if (typeof value === 'string') { |
||||
const match = value.match(/^(0x)?[0-9a-fA-F]*$/); |
||||
|
||||
if (!match) { |
||||
errors.throwError('invalid hexidecimal string', errors.INVALID_ARGUMENT, { |
||||
arg: 'value', |
||||
value, |
||||
}); |
||||
} |
||||
|
||||
if (match[1] !== '0x') { |
||||
errors.throwError( |
||||
'hex string must have 0x prefix', |
||||
errors.INVALID_ARGUMENT, |
||||
{ arg: 'value', value }, |
||||
); |
||||
} |
||||
|
||||
if (value.length % 2) { |
||||
value = '0x0' + value.substring(2); |
||||
} |
||||
return value; |
||||
} |
||||
|
||||
if (isArrayish(value)) { |
||||
const result = []; |
||||
// tslint:disable-next-line: prefer-for-of
|
||||
for (let i = 0; i < value.length; i++) { |
||||
const v = value[i]; |
||||
result.push(HexCharacters[(v & 0xf0) >> 4] + HexCharacters[v & 0x0f]); |
||||
} |
||||
return '0x' + result.join(''); |
||||
} |
||||
|
||||
errors.throwError('invalid hexlify value', null, { |
||||
arg: 'value', |
||||
value, |
||||
}); |
||||
return 'never'; |
||||
} |
||||
|
||||
export function hexDataLength(data: string) { |
||||
if (!isHexString(data) || data.length % 2 !== 0) { |
||||
return null; |
||||
} |
||||
return (data.length - 2) / 2; |
||||
} |
||||
|
||||
export function hexDataSlice( |
||||
data: string, |
||||
offset: number, |
||||
endOffset?: number, |
||||
): string { |
||||
if (!isHexString(data)) { |
||||
errors.throwError('invalid hex data', errors.INVALID_ARGUMENT, { |
||||
arg: 'value', |
||||
value: data, |
||||
}); |
||||
} |
||||
if (data.length % 2 !== 0) { |
||||
errors.throwError('hex data length must be even', errors.INVALID_ARGUMENT, { |
||||
arg: 'value', |
||||
value: data, |
||||
}); |
||||
} |
||||
offset = 2 + 2 * offset; |
||||
|
||||
if (endOffset != null) { |
||||
return '0x' + data.substring(offset, 2 + 2 * endOffset); |
||||
} |
||||
|
||||
return '0x' + data.substring(offset); |
||||
} |
||||
|
||||
export function hexStripZeros(value: string): string { |
||||
if (!isHexString(value)) { |
||||
errors.throwError('invalid hex string', errors.INVALID_ARGUMENT, { |
||||
arg: 'value', |
||||
value, |
||||
}); |
||||
} |
||||
while (value.length > 3 && value.substring(0, 3) === '0x0') { |
||||
value = '0x' + value.substring(3); |
||||
} |
||||
return value; |
||||
} |
||||
|
||||
export function hexZeroPad(value: string, length: number): string { |
||||
if (!isHexString(value)) { |
||||
errors.throwError('invalid hex string', errors.INVALID_ARGUMENT, { |
||||
arg: 'value', |
||||
value, |
||||
}); |
||||
} |
||||
|
||||
while (value.length < 2 * length + 2) { |
||||
value = '0x0' + value.substring(2); |
||||
} |
||||
return value; |
||||
} |
||||
|
||||
function isSignature(value: any): value is Signature { |
||||
return value && value.r != null && value.s != null; |
||||
} |
||||
|
||||
export function splitSignature(signature: Arrayish | Signature): Signature { |
||||
let v = 0; |
||||
let r = '0x'; |
||||
let s = '0x'; |
||||
|
||||
if (isSignature(signature)) { |
||||
if (signature.v == null && signature.recoveryParam == null) { |
||||
errors.throwError( |
||||
'at least on of recoveryParam or v must be specified', |
||||
errors.INVALID_ARGUMENT, |
||||
{ argument: 'signature', value: signature }, |
||||
); |
||||
} |
||||
r = hexZeroPad(signature.r, 32); |
||||
s = hexZeroPad(signature.s, 32); |
||||
|
||||
v = signature.v; |
||||
if (typeof v === 'string') { |
||||
v = parseInt(v, 16); |
||||
} |
||||
|
||||
let recoveryParam = signature.recoveryParam; |
||||
if (recoveryParam == null && signature.v != null) { |
||||
recoveryParam = 1 - (v % 2); |
||||
} |
||||
v = 27 + recoveryParam; |
||||
} else { |
||||
const bytes: Uint8Array = arrayify(signature); |
||||
if (bytes.length !== 65) { |
||||
throw new Error('invalid signature'); |
||||
} |
||||
r = hexlify(bytes.slice(0, 32)); |
||||
s = hexlify(bytes.slice(32, 64)); |
||||
|
||||
v = bytes[64]; |
||||
if (v !== 27 && v !== 28) { |
||||
v = 27 + (v % 2); |
||||
} |
||||
} |
||||
|
||||
return { |
||||
r, |
||||
s, |
||||
recoveryParam: v - 27, |
||||
v, |
||||
}; |
||||
} |
||||
|
||||
export function joinSignature(signature: Signature): string { |
||||
signature = splitSignature(signature); |
||||
|
||||
return hexlify( |
||||
concat([ |
||||
signature.r, |
||||
signature.s, |
||||
signature.recoveryParam ? '0x1c' : '0x1b', |
||||
]), |
||||
); |
||||
} |
@ -0,0 +1,201 @@ |
||||
// This file is ported from ether.js/src.ts/errors.ts
|
||||
|
||||
// Unknown Error
|
||||
export const UNKNOWN_ERROR = 'UNKNOWN_ERROR'; |
||||
|
||||
// Not implemented
|
||||
export const NOT_IMPLEMENTED = 'NOT_IMPLEMENTED'; |
||||
|
||||
// Missing new operator to an object
|
||||
// - name: The name of the class
|
||||
export const MISSING_NEW = 'MISSING_NEW'; |
||||
|
||||
// Call exception
|
||||
// - transaction: the transaction
|
||||
// - address?: the contract address
|
||||
// - args?: The arguments passed into the function
|
||||
// - method?: The Solidity method signature
|
||||
// - errorSignature?: The EIP848 error signature
|
||||
// - errorArgs?: The EIP848 error parameters
|
||||
// - reason: The reason (only for EIP848 "Error(string)")
|
||||
export const CALL_EXCEPTION = 'CALL_EXCEPTION'; |
||||
|
||||
// Invalid argument (e.g. value is incompatible with type) to a function:
|
||||
// - argument: The argument name that was invalid
|
||||
// - value: The value of the argument
|
||||
export const INVALID_ARGUMENT = 'INVALID_ARGUMENT'; |
||||
|
||||
// Missing argument to a function:
|
||||
// - count: The number of arguments received
|
||||
// - expectedCount: The number of arguments expected
|
||||
export const MISSING_ARGUMENT = 'MISSING_ARGUMENT'; |
||||
|
||||
// Too many arguments
|
||||
// - count: The number of arguments received
|
||||
// - expectedCount: The number of arguments expected
|
||||
export const UNEXPECTED_ARGUMENT = 'UNEXPECTED_ARGUMENT'; |
||||
|
||||
// Numeric Fault
|
||||
// - operation: the operation being executed
|
||||
// - fault: the reason this faulted
|
||||
export const NUMERIC_FAULT = 'NUMERIC_FAULT'; |
||||
|
||||
// Insufficien funds (< value + gasLimit * gasPrice)
|
||||
// - transaction: the transaction attempted
|
||||
export const INSUFFICIENT_FUNDS = 'INSUFFICIENT_FUNDS'; |
||||
|
||||
// Nonce has already been used
|
||||
// - transaction: the transaction attempted
|
||||
export const NONCE_EXPIRED = 'NONCE_EXPIRED'; |
||||
|
||||
// The replacement fee for the transaction is too low
|
||||
// - transaction: the transaction attempted
|
||||
export const REPLACEMENT_UNDERPRICED = 'REPLACEMENT_UNDERPRICED'; |
||||
|
||||
// Unsupported operation
|
||||
// - operation
|
||||
export const UNSUPPORTED_OPERATION = 'UNSUPPORTED_OPERATION'; |
||||
|
||||
// tslint:disable-next-line: variable-name
|
||||
let _permanentCensorErrors = false; |
||||
// tslint:disable-next-line: variable-name
|
||||
let _censorErrors = false; |
||||
|
||||
// @TODO: Enum
|
||||
export function throwError(message: string, code: string, params: any): never { |
||||
if (_censorErrors) { |
||||
throw new Error('unknown error'); |
||||
} |
||||
|
||||
if (!code) { |
||||
code = UNKNOWN_ERROR; |
||||
} |
||||
if (!params) { |
||||
params = {}; |
||||
} |
||||
|
||||
const messageDetails: string[] = []; |
||||
Object.keys(params).forEach((key) => { |
||||
try { |
||||
messageDetails.push(key + '=' + JSON.stringify(params[key])); |
||||
} catch (error) { |
||||
messageDetails.push(key + '=' + JSON.stringify(params[key].toString())); |
||||
} |
||||
}); |
||||
messageDetails.push('version=' + '#version'); |
||||
|
||||
const reason = message; |
||||
if (messageDetails.length) { |
||||
message += ' (' + messageDetails.join(', ') + ')'; |
||||
} |
||||
|
||||
// @TODO: Any??
|
||||
const error: any = new Error(message); |
||||
error.reason = reason; |
||||
error.code = code; |
||||
|
||||
Object.keys(params).forEach((key) => { |
||||
error[key] = params[key]; |
||||
}); |
||||
|
||||
throw error; |
||||
} |
||||
|
||||
export function checkNew(self: any, kind: any): void { |
||||
if (!(self instanceof kind)) { |
||||
throwError('missing new', MISSING_NEW, { name: kind.name }); |
||||
} |
||||
} |
||||
|
||||
export function checkArgumentCount( |
||||
count: number, |
||||
expectedCount: number, |
||||
suffix?: string, |
||||
): void { |
||||
if (!suffix) { |
||||
suffix = ''; |
||||
} |
||||
if (count < expectedCount) { |
||||
throwError('missing argument' + suffix, MISSING_ARGUMENT, { |
||||
count, |
||||
expectedCount, |
||||
}); |
||||
} |
||||
if (count > expectedCount) { |
||||
throwError('too many arguments' + suffix, UNEXPECTED_ARGUMENT, { |
||||
count, |
||||
expectedCount, |
||||
}); |
||||
} |
||||
} |
||||
|
||||
export function setCensorship(censorship: boolean, permanent?: boolean): void { |
||||
if (_permanentCensorErrors) { |
||||
throwError('error censorship permanent', UNSUPPORTED_OPERATION, { |
||||
operation: 'setCensorship', |
||||
}); |
||||
} |
||||
|
||||
_censorErrors = !!censorship; |
||||
_permanentCensorErrors = !!permanent; |
||||
} |
||||
|
||||
export function checkNormalize(): void { |
||||
try { |
||||
// Make sure all forms of normalization are supported
|
||||
['NFD', 'NFC', 'NFKD', 'NFKC'].forEach((form) => { |
||||
try { |
||||
'test'.normalize(form); |
||||
} catch (error) { |
||||
throw new Error('missing ' + form); |
||||
} |
||||
}); |
||||
|
||||
if ( |
||||
String.fromCharCode(0xe9).normalize('NFD') !== |
||||
String.fromCharCode(0x65, 0x0301) |
||||
) { |
||||
throw new Error('broken implementation'); |
||||
} |
||||
} catch (error) { |
||||
throwError( |
||||
'platform missing String.prototype.normalize', |
||||
UNSUPPORTED_OPERATION, |
||||
{ operation: 'String.prototype.normalize', form: error.message }, |
||||
); |
||||
} |
||||
} |
||||
|
||||
const LogLevels: { [name: string]: number } = { |
||||
debug: 1, |
||||
default: 2, |
||||
info: 2, |
||||
warn: 3, |
||||
error: 4, |
||||
off: 5, |
||||
}; |
||||
let LogLevel = LogLevels.default; |
||||
|
||||
export function setLogLevel(logLevel: string): void { |
||||
const level = LogLevels[logLevel]; |
||||
if (level == null) { |
||||
warn('invliad log level - ' + logLevel); |
||||
return; |
||||
} |
||||
LogLevel = level; |
||||
} |
||||
|
||||
function log(logLevel: string, args: any[]): void { |
||||
if (LogLevel > LogLevels[logLevel]) { |
||||
return; |
||||
} |
||||
console.log.apply(console, args); |
||||
} |
||||
|
||||
export function warn(...args: any[]): void { |
||||
log('warn', args); |
||||
} |
||||
|
||||
export function info(...args: any[]): void { |
||||
log('info', args); |
||||
} |
@ -1 +1,2 @@ |
||||
export { randomBytes } from './random'; |
||||
export * from './random'; |
||||
export * from './keyTool'; |
||||
|
@ -0,0 +1,7 @@ |
||||
import * as sha3 from 'js-sha3'; |
||||
|
||||
import { arrayify, Arrayish } from './bytes'; |
||||
|
||||
export function keccak256(data: Arrayish): string { |
||||
return '0x' + sha3.keccak_256(arrayify(data)); |
||||
} |
@ -0,0 +1,69 @@ |
||||
import elliptic from 'elliptic'; |
||||
import * as bytes from './bytes'; |
||||
import * as errors from './errors'; |
||||
import { keccak256 } from './keccak256'; |
||||
import { randomBytes } from './random'; |
||||
|
||||
const secp256k1 = elliptic.ec('secp256k1'); |
||||
|
||||
export const generatePrivateKey = (): string => { |
||||
const entropy: string = '0x' + randomBytes(16); |
||||
const innerHex: string = keccak256( |
||||
bytes.concat(['0x' + randomBytes(32), entropy || '0x' + randomBytes(32)]), |
||||
); |
||||
const middleHex: Uint8Array = bytes.concat([ |
||||
bytes.concat(['0x' + randomBytes(32), innerHex]), |
||||
'0x' + randomBytes(32), |
||||
]); |
||||
const outerHex: string = keccak256(middleHex); |
||||
return outerHex; |
||||
}; |
||||
|
||||
export const getPubkeyFromPrivateKey = (privateKey: string): string => { |
||||
const buffer = new Buffer(privateKey.slice(2), 'hex'); |
||||
const ecKey = secp256k1.keyFromPrivate(buffer); |
||||
const pubK = '0x' + ecKey.getPublic(false, 'hex').slice(2); |
||||
const publicKey = keccak256(pubK); |
||||
return publicKey; |
||||
}; |
||||
|
||||
export const getAddressFromPrivateKey = (privateKey: string): string => { |
||||
const publicKey = getPubkeyFromPrivateKey(privateKey); |
||||
const address = '0x' + publicKey.slice(-40); |
||||
return address; |
||||
}; |
||||
|
||||
export const getAddressFromPublicKey = (publicKey: string): string => { |
||||
const address = '0x' + publicKey.slice(-40); |
||||
return address; |
||||
}; |
||||
|
||||
export const toChecksumAddress = (address: string): string => { |
||||
if (typeof address !== 'string' || !address.match(/^0x[0-9A-Fa-f]{40}$/)) { |
||||
errors.throwError('invalid address', errors.INVALID_ARGUMENT, { |
||||
arg: 'address', |
||||
value: address, |
||||
}); |
||||
} |
||||
|
||||
address = address.toLowerCase(); |
||||
|
||||
const chars = address.substring(2).split(''); |
||||
|
||||
let hashed = new Uint8Array(40); |
||||
for (let i = 0; i < 40; i++) { |
||||
hashed[i] = chars[i].charCodeAt(0); |
||||
} |
||||
hashed = bytes.arrayify(keccak256(hashed)); |
||||
|
||||
for (let i = 0; i < 40; i += 2) { |
||||
if (hashed[i >> 1] >> 4 >= 8) { |
||||
chars[i] = chars[i].toUpperCase(); |
||||
} |
||||
if ((hashed[i >> 1] & 0x0f) >= 8) { |
||||
chars[i + 1] = chars[i + 1].toUpperCase(); |
||||
} |
||||
} |
||||
|
||||
return '0x' + chars.join(''); |
||||
}; |
@ -0,0 +1,4 @@ |
||||
{ |
||||
"extends": "../../tsconfig.base.json", |
||||
"include": ["src", "../../typings/**/*.d.ts"] |
||||
} |
@ -0,0 +1,61 @@ |
||||
import BN from 'bn.js'; |
||||
import hash from 'hash.js'; |
||||
|
||||
declare namespace Elliptic { |
||||
type HexEnc = 'hex'; |
||||
type Utf8Enc = 'utf8'; |
||||
type CurveTypes = 'short' | 'edwards' | 'mont'; |
||||
type PrivateKey = |
||||
| string |
||||
| Buffer |
||||
| { x: Buffer; y: Buffer } |
||||
| { x: string; y: string }; |
||||
|
||||
interface Curve { |
||||
type: CurveTypes; |
||||
n: BN; |
||||
g: Point; |
||||
decodePoint(msg: Buffer | Array<any> | string, enc?: string): Point; |
||||
validate(point: Point): boolean; |
||||
} |
||||
|
||||
interface Point { |
||||
x: BN; |
||||
y: BN; |
||||
inf: boolean; |
||||
encode(enc: string, compressed?: boolean): Array<number>; |
||||
encodeCompressed(enc?: string): Array<number>; |
||||
isInfinity(): boolean; |
||||
add(k: BN | Number | Point): Point; |
||||
mul(k: BN | Number | Point): Point; |
||||
} |
||||
|
||||
interface EC { |
||||
curve: Curve; |
||||
genKeyPair(opt?: GenKeyPairOpt): KeyPair; |
||||
keyFromPrivate(priv: string, enc: string): KeyPair; |
||||
keyFromPublic(pub: string, enc: string): KeyPair; |
||||
} |
||||
|
||||
interface GenKeyPairOpt { |
||||
entropy?: string | Buffer; |
||||
entropyEnc?: HexEnc | Utf8Enc; |
||||
pers?: string | Buffer; |
||||
persEnc?: HexEnc | Utf8Enc; |
||||
} |
||||
|
||||
interface KeyPair { |
||||
fromPublic(ec: Curve, pub: BN, enc: string): KeyPair; |
||||
fromPrivate(ec: Curve, priv: BN, enc: string): KeyPair; |
||||
// this is broken, but we can't fix it without changing the upstream
|
||||
// library; compact is optional, but optional parameters should always
|
||||
// _follow_ mandatory ones.
|
||||
getPublic(compact: boolean, enc: string): string; |
||||
getPrivate<T = undefined>(enc?: T): T extends HexEnc ? string : BN; |
||||
validate(): { result: boolean; reason: string | null }; |
||||
} |
||||
|
||||
export function ec(curve: string): EC; |
||||
} |
||||
|
||||
export = Elliptic; |
@ -0,0 +1,67 @@ |
||||
const path = require('path'); |
||||
const UglifyJs = require('uglifyjs-webpack-plugin'); |
||||
const packagesSettings = require('./scripts/packagesList'); |
||||
|
||||
function createBatchConfig(list) { |
||||
return list.map((l) => { |
||||
const entryBase = {}; |
||||
entryBase[l.name] = [`./packages/${l.dest}/lib/index.js`]; |
||||
|
||||
const batchBaseConfig = { |
||||
entry: entryBase, |
||||
mode: 'production', |
||||
module: { |
||||
rules: [ |
||||
{ |
||||
test: /\.js$/, |
||||
use: { |
||||
loader: 'babel-loader', |
||||
}, |
||||
}, |
||||
], |
||||
}, |
||||
devtool: 'source-map', |
||||
resolve: { |
||||
symlinks: true, |
||||
extensions: ['.js'], |
||||
}, |
||||
}; |
||||
|
||||
const batchClientConfig = { |
||||
...batchBaseConfig, |
||||
optimization: { |
||||
minimizer: [ |
||||
new UglifyJs({ |
||||
uglifyOptions: { |
||||
compress: true, |
||||
mangle: true, |
||||
toplevel: false, |
||||
output: { |
||||
beautify: false, |
||||
comments: false, |
||||
}, |
||||
}, |
||||
parallel: true, |
||||
sourceMap: true, |
||||
}), |
||||
], |
||||
}, |
||||
output: { |
||||
libraryTarget: 'umd', |
||||
library: `${l.name}`, |
||||
filename: '[name].browser.js', |
||||
path: path.join(__dirname, 'dist'), |
||||
}, |
||||
}; |
||||
|
||||
return [batchBaseConfig, batchClientConfig]; |
||||
}); |
||||
} |
||||
|
||||
function reduceDimension(arr) { |
||||
return Array.prototype.concat.apply([], arr); |
||||
} |
||||
|
||||
const batch = reduceDimension(createBatchConfig(packagesSettings)); |
||||
|
||||
module.exports = batch; |
Loading…
Reference in new issue