UNPKG

3.84 kBPlain TextView Raw
1import BN from 'bn.js'
2import { isHexString } from './internal'
3import { Address } from './address'
4import { unpadBuffer, toBuffer, ToBufferInputTypes } from './bytes'
5
6/*
7 * A type that represents a BNLike input that can be converted to a BN.
8 */
9export type BNLike = BN | PrefixedHexString | number | Buffer
10
11/*
12 * A type that represents a BufferLike input that can be converted to a Buffer.
13 */
14export type BufferLike =
15 | Buffer
16 | Uint8Array
17 | number[]
18 | number
19 | BN
20 | TransformableToBuffer
21 | PrefixedHexString
22
23/*
24 * A type that represents a `0x`-prefixed hex string.
25 */
26export type PrefixedHexString = string
27
28/**
29 * A type that represents an Address-like value.
30 * To convert to address, use `new Address(toBuffer(value))`
31 */
32export type AddressLike = Address | Buffer | PrefixedHexString
33
34/*
35 * A type that represents an object that has a `toArray()` method.
36 */
37export interface TransformableToArray {
38 toArray(): Uint8Array
39 toBuffer?(): Buffer
40}
41
42/*
43 * A type that represents an object that has a `toBuffer()` method.
44 */
45export interface TransformableToBuffer {
46 toBuffer(): Buffer
47 toArray?(): Uint8Array
48}
49
50/**
51 * Convert BN to 0x-prefixed hex string.
52 */
53export function bnToHex(value: BN): PrefixedHexString {
54 return `0x${value.toString(16)}`
55}
56
57/**
58 * Convert value from BN to an unpadded Buffer
59 * (useful for RLP transport)
60 * @param value value to convert
61 */
62export function bnToUnpaddedBuffer(value: BN): Buffer {
63 // Using `bn.toArrayLike(Buffer)` instead of `bn.toBuffer()`
64 // for compatibility with browserify and similar tools
65 return unpadBuffer(value.toArrayLike(Buffer))
66}
67
68/**
69 * Deprecated alias for {@link bnToUnpaddedBuffer}
70 * @deprecated
71 */
72export function bnToRlp(value: BN): Buffer {
73 return bnToUnpaddedBuffer(value)
74}
75
76/**
77 * Type output options
78 */
79export enum TypeOutput {
80 Number,
81 BN,
82 Buffer,
83 PrefixedHexString,
84}
85
86export type TypeOutputReturnType = {
87 [TypeOutput.Number]: number
88 [TypeOutput.BN]: BN
89 [TypeOutput.Buffer]: Buffer
90 [TypeOutput.PrefixedHexString]: PrefixedHexString
91}
92
93/**
94 * Convert an input to a specified type.
95 * Input of null/undefined returns null/undefined regardless of the output type.
96 * @param input value to convert
97 * @param outputType type to output
98 */
99export function toType<T extends TypeOutput>(input: null, outputType: T): null
100export function toType<T extends TypeOutput>(input: undefined, outputType: T): undefined
101export function toType<T extends TypeOutput>(
102 input: ToBufferInputTypes,
103 outputType: T
104): TypeOutputReturnType[T]
105export function toType<T extends TypeOutput>(
106 input: ToBufferInputTypes,
107 outputType: T
108): TypeOutputReturnType[T] | undefined | null {
109 if (input === null) {
110 return null
111 }
112 if (input === undefined) {
113 return undefined
114 }
115
116 if (typeof input === 'string' && !isHexString(input)) {
117 throw new Error(`A string must be provided with a 0x-prefix, given: ${input}`)
118 } else if (typeof input === 'number' && !Number.isSafeInteger(input)) {
119 throw new Error(
120 'The provided number is greater than MAX_SAFE_INTEGER (please use an alternative input type)'
121 )
122 }
123
124 const output = toBuffer(input)
125
126 if (outputType === TypeOutput.Buffer) {
127 return output as TypeOutputReturnType[T]
128 } else if (outputType === TypeOutput.BN) {
129 return new BN(output) as TypeOutputReturnType[T]
130 } else if (outputType === TypeOutput.Number) {
131 const bn = new BN(output)
132 const max = new BN(Number.MAX_SAFE_INTEGER.toString())
133 if (bn.gt(max)) {
134 throw new Error(
135 'The provided number is greater than MAX_SAFE_INTEGER (please use an alternative output type)'
136 )
137 }
138 return bn.toNumber() as TypeOutputReturnType[T]
139 } else {
140 // outputType === TypeOutput.PrefixedHexString
141 return `0x${output.toString('hex')}` as TypeOutputReturnType[T]
142 }
143}