import axios from 'axios' ; import { BigNumber } from 'bignumber.js' ; import * as bip39 from 'bip39' ; import * as BN from 'bn.js' ; import * as cryptoJS from 'crypto-js' ; import * as numberToBN from 'number-to-bn' ; import * as secureRandom from 'secure-random' ; import { UNBOUND_GENERATION_AMOUNT , UNBOUND_TIME_INTERVAL , WEBVIEW_SCHEME } from './consts' ; import { ERROR_CODE } from './error' ; param str export function hexstring2ab ( str ) { const result = [ ] ; while ( str . length >= 2 ) { result . push ( parseInt ( str . substring ( 0 , 2 ) , 16 ) ) ; str = str . substring ( 2 , str . length ) ; } return result ; } param arr export function ab2hexstring ( arr ) { let result = '' ; const uint8Arr = new Uint8Array ( arr ) ; for ( let i = 0 ; i < uint8Arr . byteLength ; i ++ ) { let str = uint8Arr [ i ] . toString ( 16 ) ; str = str . length === 0 ? '00' : str . length === 1 ? '0' + str : str ; result += str ; } return result ; } param buf export function ab2str ( buf ) { let out , i , len , c ; let char2 , char3 ; out = '' ; const array = new Uint8Array ( buf ) ; len = array . length ; i = 0 ; while ( i < len ) { c = array [ i ++ ] ; switch ( c >> 4 ) { case 0 : case 1 : case 2 : case 3 : case 4 : case 5 : case 6 : case 7 : out += String . fromCharCode ( c ) ; break ; case 12 : case 13 : char2 = array [ i ++ ] ; out += String . fromCharCode ( ( ( c & 0x1F ) << 6 ) | ( char2 & 0x3F ) ) ; break ; case 14 : char2 = array [ i ++ ] ; char3 = array [ i ++ ] ; out += String . fromCharCode ( ( ( c & 0x0F ) << 12 ) | ( ( char2 & 0x3F ) << 6 ) | ( ( char3 & 0x3F ) << 0 ) ) ; break ; } } return out ; } param str export function str2ab ( str ) { const utf8 = [ ] ; for ( let i = 0 ; i < str . length ; i ++ ) { let charcode = str . charCodeAt ( i ) ; if ( charcode < 0x80 ) { utf8 . push ( charcode ) ; } else if ( charcode < 0x800 ) { utf8 . push ( 0xc0 | ( charcode >> 6 ) , 0x80 | ( charcode & 0x3f ) ) ; } else if ( charcode < 0xd800 || charcode >= 0xe000 ) { utf8 . push ( 0xe0 | ( charcode >> 12 ) , 0x80 | ( ( charcode >> 6 ) & 0x3f ) , 0x80 | ( charcode & 0x3f ) ) ; } else { i ++ ; charcode = 0x10000 + ( ( ( charcode & 0x3ff ) << 10 ) | ( str . charCodeAt ( i ) & 0x3ff ) ) ; utf8 . push ( 0xf0 | ( charcode >> 18 ) , 0x80 | ( ( charcode >> 12 ) & 0x3f ) , 0x80 | ( ( charcode >> 6 ) & 0x3f ) , 0x80 | ( charcode & 0x3f ) ) ; } } return Uint8Array . from ( utf8 ) ; } param str export function str2hexstr ( str ) { return ab2hexstring ( str2ab ( str ) ) ; } param str export function hexstr2str ( str ) { return ab2str ( hexstring2ab ( str ) ) ; } param hex export function hex2VarBytes ( hex ) { let result = '' ; result += num2VarInt ( hex . length / 2 ) ; result += hex ; return result ; } param str export function str2VarBytes ( str ) { let result = '' ; const hex = str2hexstr ( str ) ; const hexLen = num2VarInt ( hex . length / 2 ) ; result += hexLen ; result += hex ; return result ; } param v export function bool2VarByte ( v ) { return v ? '01' : '00' ; } param str1 param str2 export function hexXor ( str1 , str2 ) { if ( str1 . length !== str2 . length ) { throw new Error ( 'strings are disparate lengths' ) ; } if ( str1 . length % 2 !== 0 ) { throw new Error ( 'strings must be hex' ) ; } const result = new ArrayBuffer ( str1 . length / 2 ) ; const result8 = new Uint8Array ( result ) ; for ( let i = 0 ; i < str1 . length ; i += 2 ) { result8 [ i / 2 ] = ( parseInt ( str1 . substr ( i , 2 ) , 16 ) ^ parseInt ( str2 . substr ( i , 2 ) , 16 ) ) ; } return ab2hexstring ( result ) ; } param { number } num param { number } size param { boolean } littleEndian return { string } export const num2hexstring = ( num , size = 1 , littleEndian = false ) => { if ( num < 0 ) { throw new RangeError ( 'num must be >=0' ) ; } if ( size % 1 !== 0 ) { throw new Error ( 'size must be a whole integer' ) ; } if ( ! Number . isSafeInteger ( num ) ) { throw new RangeError ( `num (${ num }) must be a safe integer` ) ; } size = size * 2 ; let hexstring = num . toString ( 16 ) ; hexstring = hexstring . length % size === 0 ? hexstring : ( '0' . repeat ( size ) + hexstring ) . substring ( hexstring . length ) ; if ( littleEndian ) { hexstring = reverseHex ( hexstring ) ; } return hexstring ; } ; param { number } num returns { string } export const num2VarInt = ( num ) => { if ( num < 0xfd ) { return num2hexstring ( num ) ; } else if ( num <= 0xffff ) { return 'fd' + num2hexstring ( num , 2 , true ) ; } else if ( num <= 0xffffffff ) { return 'fe' + num2hexstring ( num , 4 , true ) ; } else { return 'ff' + num2hexstring ( num , 8 , true ) ; } } ; example param { string } hex return { string } export const reverseHex = ( hex ) => { if ( hex . length % 2 !== 0 ) { throw new Error ( `Incorrect Length: ${ hex }` ) ; } let out = '' ; for ( let i = hex . length - 2 ; i >= 0 ; i -= 2 ) { out += hex . substr ( i , 2 ) ; } return out ; } ; export function bigIntFromBytes ( bytes ) { const bs = Buffer . from ( bytes , 'hex' ) . reverse ( ) ; if ( bs . length === 0 ) { return '0' ; } const bn = new BN ( bs ) . fromTwos ( bs . length * 8 ) ; return bn . toString ( ) ; } export function bigIntToBytes ( value ) { const bn = value instanceof BigNumber ? numberToBN ( value ) : numberToBN ( new BigNumber ( value ) ) ; if ( bn . isZero ( ) ) { return '' ; } const bs = bn . toTwos ( bn . byteLength ( ) * 8 ) . toArray ( ) ; if ( bn . isNeg ( ) ) { if ( bs [ 0 ] < 128 ) { bs . unshift ( 255 ) ; } } else if ( bs [ 0 ] >= 128 ) { bs . unshift ( 0 ) ; } return Buffer . from ( bs . reverse ( ) ) . toString ( 'hex' ) ; } class classdesc param { string } str export class StringReader { str : string ; pos : number ; size : number ; constructor ( str = '' ) { if ( str . length % 2 !== 0 ) { throw new Error ( 'Param\'s length is not even.' ) ; } this . str = str ; this . pos = 0 ; this . size = this . str . length / 2 ; } /**
     * Checks if reached the end of the string.
     */ isEmpty ( ) { return this . pos >= this . str . length ; } param { number } bytes read ( bytes ) { if ( this . isEmpty ( ) ) { throw new Error ( 'StringReader reached the end.' ) ; } const out = this . str . substr ( this . pos , bytes * 2 ) ; this . pos += bytes * 2 ; return out ; } unreadBytes ( bytes ) { if ( ( this . pos - bytes * 2 ) < 0 ) { throw new Error ( 'Can not unread too many bytes.' ) ; } this . pos -= bytes * 2 ; return ; } /**
     * Reads string terminated by NULL.
     */ readNullTerminated ( ) { const index = this . str . indexOf ( '00' , this . pos ) ; if ( index === - 1 ) { throw new Error ( 'No ending NULL found' ) ; } const out = this . str . substring ( this . pos , index ) ; this . pos = index + 2 ; return out ; } readNextByte ( ) { return this . read ( 1 ) ; } /**
     * First, read one byte as the length of bytes to read. Then read the following bytes.
     */ readNextBytes ( ) { const bytesToRead = this . readNextLen ( ) ; if ( bytesToRead === 0 ) { return '' ; } return this . read ( bytesToRead ) ; } returns { number } readNextLen ( ) { let len = parseInt ( this . read ( 1 ) , 16 ) ; if ( len === 0xfd ) { len = parseInt ( reverseHex ( this . read ( 2 ) ) , 16 ) ; } else if ( len === 0xfe ) { len = parseInt ( reverseHex ( this . read ( 4 ) ) , 16 ) ; } else if ( len === 0xff ) { len = parseInt ( reverseHex ( this . read ( 8 ) ) , 16 ) ; } return len ; } readVarUint ( ) { return this . readNextLen ( ) ; } /**
     * Read Uint8
     */ readUint8 ( ) { return parseInt ( reverseHex ( this . read ( 1 ) ) , 16 ) ; } /**
     * read 2 bytes as uint16 in littleEndian
     */ readUint16 ( ) { return parseInt ( reverseHex ( this . read ( 2 ) ) , 16 ) ; } /**
     * Read 4 bytes as uint32 in littleEndian
     */ readUint32 ( ) { return parseInt ( reverseHex ( this . read ( 4 ) ) , 16 ) ; } /**
     * Read 8 bytes as uint64 in littleEndian
     */ readUint64 ( ) { return parseInt ( reverseHex ( this . read ( 8 ) ) , 16 ) ; } readUint128 ( ) { return parseInt ( reverseHex ( this . read ( 16 ) ) , 16 ) ; } /**
     * Read 4 bytes as int in littleEndian
     */ readInt ( ) { return parseInt ( reverseHex ( this . read ( 4 ) ) , 16 ) ; } /**
     * Read 8 bytes as long in littleEndian
     */ readLong ( ) { return parseInt ( reverseHex ( this . read ( 8 ) ) , 16 ) ; } readBoolean ( ) { return parseInt ( this . read ( 1 ) , 16 ) !== 0 ; } readH256 ( ) { return this . read ( 32 ) ; } } export class EventEmitter { handlers : any = { } ; on ( type , handler ) { if ( typeof this . handlers [ type ] === 'undefined' ) { this . handlers [ type ] = [ ] ; } this . handlers [ type ] . push ( handler ) ; } param { string } type param { any } event trigger ( type , event ? ) { if ( this . handlers [ type ] instanceof Array ) { const handlers = this . handlers [ type ] ; for ( let i = 0 , len = handlers . length ; i < len ; i ++ ) { handlers [ i ] ( event ) ; } } } off ( type ) { delete this . handlers [ type ] ; } } export const sendBackResult2Native = ( result , callback ) => { if ( window && window . prompt ) { window . prompt ( `${ WEBVIEW_SCHEME }://${ callback }?params=${ result }` ) ; } } ; export const axiosPost = ( url , params ) => { return axios . post ( url , params ) . then ( ( res ) => { console . log ( 'axios res:' + res ) ; return res ; } ) . catch ( ( err ) => { console . log ( 'axios res:' + JSON . stringify ( err ) ) ; return err ; } ) ; } ; /**
 * Gets current time in unix timestamp format.
 */ export function now ( ) { return Math . floor ( Date . now ( ) / 1000 ) ; } param data export function sha256 ( data ) { const hex = cryptoJS . enc . Hex . parse ( data ) ; const sha = cryptoJS . SHA256 ( hex ) . toString ( ) ; return sha ; } param data export function ripemd160 ( data ) { const hex = cryptoJS . enc . Hex . parse ( data ) ; const ripemd = cryptoJS . RIPEMD160 ( hex ) . toString ( ) ; return ripemd ; } param data export function hash160 ( SignatureScript ) { return ripemd160 ( sha256 ( SignatureScript ) ) ; } param len export function generateRandomArray ( len ) { return secureRandom ( len ) ; } param len export function randomBytes ( len ) { return ab2hexstring ( generateRandomArray ( len ) ) ; } export function generateMnemonic ( size = 16 ) { const random = ab2hexstring ( generateRandomArray ( size ) ) ; return bip39 . entropyToMnemonic ( random ) ; } export function parseMnemonic ( str ) { return bip39 . mnemonicToEntropy ( str ) ; } export function varifyPositiveInt ( v ) { if ( ! /^[1-9]\d*$/ . test ( v . toString ( ) ) ) { throw ERROR_CODE . INVALID_PARAMS ; } return ; } export function isBase64 ( str ) { return Buffer . from ( str , 'base64' ) . toString ( 'base64' ) === str ; } export function isHexString ( str ) { const regexp = /^[0-9a-fA-F]+$/ ; return regexp . test ( str ) && ( str . length % 2 === 0 ) ; } export function unboundDeadline ( ) { const start = Math . floor ( Date . UTC ( 2018 , 5 , 30 , 0 , 0 , 0 ) / 1000 ) ; const end = Math . floor ( Date . UTC ( 2020 , 6 , 7 , 0 , 0 , 0 ) / 1000 ) ; return end - start ; } export function calcUnboundOng ( balance , startOffset , endOffset ) { let amount = 0 ; if ( startOffset >= endOffset ) { return 0 ; } const UNBOUND_DEADLINE = unboundDeadline ( ) ; if ( startOffset < UNBOUND_DEADLINE ) { let ustart = Math . floor ( startOffset / UNBOUND_TIME_INTERVAL ) ; let istart = startOffset % UNBOUND_TIME_INTERVAL ; if ( endOffset >= UNBOUND_DEADLINE ) { endOffset = UNBOUND_DEADLINE ; } const uend = Math . floor ( endOffset / UNBOUND_TIME_INTERVAL ) ; const iend = endOffset % UNBOUND_TIME_INTERVAL ; while ( ustart < uend ) { amount += ( UNBOUND_TIME_INTERVAL - istart ) * UNBOUND_GENERATION_AMOUNT [ ustart ] ; ustart ++ ; istart = 0 ; } amount += ( iend - istart ) * UNBOUND_GENERATION_AMOUNT [ ustart ] ; } return amount * balance ; }