packageDocumentation module hidden import * as errors from './errors' ; export type Arrayish = string | ArrayLike < number > ; export interface Hexable { toHexString ( ) : string ; } export interface Signature { r : string ; s : string ; recoveryParam ? : number ; v ? : number ; } export function isHexable ( value ) { return ! ! value . toHexString ; } function addSlice ( array ) { if ( typeof array === 'object' && typeof array . slice === 'function' ) { return array ; } array . slice = function ( ) { const args = Array . prototype . slice . call ( arguments ) ; return addSlice ( new Uint8Array ( Array . prototype . slice . apply ( array , [ args [ 0 ] , args [ 1 ] ] ) ) ) ; } ; return array ; } export function isArrayish ( value ) { if ( ! value || parseInt ( String ( value . length ) ) !== value . length || typeof value === 'string' ) { return false ; } for ( let i = 0 ; i < value . length ; i ++ ) { const v = value [ i ] ; if ( v < 0 || v >= 256 || parseInt ( String ( v ) ) !== v ) { return false ; } } return true ; } export function arrayify ( value ) { 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 !== null && 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 ) { if ( objects === null ) { throw new Error ( `concat objects is null` ) ; } const arrays = [ ] ; let length = 0 ; for ( let i = 0 ; i < objects . length ; i ++ ) { const object = arrayify ( objects [ i ] ) ; if ( object == null ) { throw new Error ( 'arrayify failed' ) ; } arrays . push ( object ) ; length += object . length ; } const result = new Uint8Array ( length ) ; let offset = 0 ; for ( let i = 0 ; i < arrays . length ; i ++ ) { result . set ( arrays [ i ] , offset ) ; offset += arrays [ i ] . length ; } return addSlice ( result ) ; } export function stripZeros ( value ) { let result = arrayify ( value ) ; if ( result === null ) { throw new Error ( 'arrayify failed' ) ; } if ( result . length === 0 ) { return result ; } let start = 0 ; while ( result [ start ] === 0 ) { start ++ ; } if ( start ) { result = result . slice ( start ) ; } return result ; } export function padZeros ( value , length ) { const arrayifyValue = arrayify ( value ) ; if ( arrayifyValue === null ) { throw new Error ( 'arrayify failed' ) ; } if ( length < arrayifyValue . length ) { throw new Error ( 'cannot pad' ) ; } const result = new Uint8Array ( length ) ; result . set ( arrayifyValue , length - arrayifyValue . length ) ; return addSlice ( result ) ; } export function isHexString ( value , length ? ) { 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 = '0123456789abcdef' ; export function hexlify ( value ) { 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 , } ) ; } 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 !== null && 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 = [ ] ; 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 ) { if ( ! isHexString ( data ) || data . length % 2 !== 0 ) { return null ; } return ( data . length - 2 ) / 2 ; } export function hexDataSlice ( data , offset , endOffset ? ) { 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 ) { 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 , length ) { 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 ; } export function bytesPadLeft ( value , byteLength ) { if ( ! isHexString ( value ) ) { errors . throwError ( 'invalid hex string' , errors . INVALID_ARGUMENT , { arg : 'value' , value , } ) ; } const striped = value . substring ( 2 ) ; if ( striped . length > byteLength * 2 ) { throw new Error ( `hex string length = ${ striped . length } beyond byteLength=${ byteLength }` ) ; } const padLength = byteLength * 2 - striped . length ; const returnValue = '0x' + '0' . repeat ( padLength ) + striped ; return returnValue ; } export function bytesPadRight ( value , byteLength ) { if ( ! isHexString ( value ) ) { errors . throwError ( 'invalid hex string' , errors . INVALID_ARGUMENT , { arg : 'value' , value , } ) ; } const striped = value . substring ( 2 ) ; if ( striped . length > byteLength * 2 ) { throw new Error ( `hex string length = ${ striped . length } beyond byteLength=${ byteLength }` ) ; } const padLength = byteLength * 2 - striped . length ; const returnValue = '0x' + striped + '0' . repeat ( padLength ) ; return returnValue ; } export function isSignature ( value ) { return value && value . r != null && value . s != null ; } export function splitSignature ( signature ) { if ( signature !== undefined ) { 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 || 0 ; if ( typeof v === 'string' ) { v = parseInt ( v , 16 ) ; } let recoveryParam = signature . recoveryParam || 0 ; if ( recoveryParam == null && signature . v != null ) { recoveryParam = 1 - ( v % 2 ) ; } v = 27 + recoveryParam ; } else { const bytes = arrayify ( signature ) || new Uint8Array ( ) ; 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 , } ; } else { throw new Error ( 'signature is not found' ) ; } } export function joinSignature ( signature ) { signature = splitSignature ( signature ) ; return hexlify ( concat ( [ signature . r , signature . s , signature . recoveryParam ? '0x1c' : '0x1b' ] ) ) ; } param { string } hex returns { Uint8Array } export const hexToByteArray = ( hex ) : Uint8Array => { const res = new Uint8Array ( hex . length / 2 ) ; for ( let i = 0 ; i < hex . length ; i += 2 ) { res [ i / 2 ] = parseInt ( hex . substring ( i , i + 2 ) , 16 ) ; } return res ; } ; param { string } hex returns { number [ ] } export const hexToIntArray = ( hex ) : number [ ] => { if ( ! hex || ! isHex ( hex ) ) { return [ ] ; } const res = [ ] ; for ( let i = 0 ; i < hex . length ; i ++ ) { const c = hex . charCodeAt ( i ) ; const hi = c >> 8 ; const lo = c & 0xff ; hi ? res . push ( hi , lo ) : res . push ( lo ) ; } return res ; } ; param { string } str returns { boolean } export const isHex = ( str ) : boolean => { const plain = str . replace ( '0x' , '' ) ; return /[0-9a-f]*$/i . test ( plain ) ; } ;