web3util 4.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/3xg6ulq8.cjs +1 -0
- package/LICENSE +14 -0
- package/README.md +72 -0
- package/lib/commonjs/chunk_response_parser.d.ts +14 -0
- package/lib/commonjs/chunk_response_parser.js +66 -0
- package/lib/commonjs/chunk_response_parser.js.map +1 -0
- package/lib/commonjs/converters.d.ts +280 -0
- package/lib/commonjs/converters.js +624 -0
- package/lib/commonjs/converters.js.map +1 -0
- package/lib/commonjs/event_emitter.d.ts +10 -0
- package/lib/commonjs/event_emitter.js +44 -0
- package/lib/commonjs/event_emitter.js.map +1 -0
- package/lib/commonjs/formatter.d.ts +43 -0
- package/lib/commonjs/formatter.js +320 -0
- package/lib/commonjs/formatter.js.map +1 -0
- package/lib/commonjs/hash.d.ts +93 -0
- package/lib/commonjs/hash.js +347 -0
- package/lib/commonjs/hash.js.map +1 -0
- package/lib/commonjs/index.d.ts +18 -0
- package/lib/commonjs/index.js +63 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/json_rpc.d.ts +21 -0
- package/lib/commonjs/json_rpc.js +96 -0
- package/lib/commonjs/json_rpc.js.map +1 -0
- package/lib/commonjs/objects.d.ts +7 -0
- package/lib/commonjs/objects.js +62 -0
- package/lib/commonjs/objects.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/promise_helpers.d.ts +47 -0
- package/lib/commonjs/promise_helpers.js +155 -0
- package/lib/commonjs/promise_helpers.js.map +1 -0
- package/lib/commonjs/random.d.ts +28 -0
- package/lib/commonjs/random.js +55 -0
- package/lib/commonjs/random.js.map +1 -0
- package/lib/commonjs/socket_provider.d.ts +128 -0
- package/lib/commonjs/socket_provider.js +356 -0
- package/lib/commonjs/socket_provider.js.map +1 -0
- package/lib/commonjs/string_manipulation.d.ts +80 -0
- package/lib/commonjs/string_manipulation.js +147 -0
- package/lib/commonjs/string_manipulation.js.map +1 -0
- package/lib/commonjs/uint8array.d.ts +6 -0
- package/lib/commonjs/uint8array.js +59 -0
- package/lib/commonjs/uint8array.js.map +1 -0
- package/lib/commonjs/uuid.d.ts +11 -0
- package/lib/commonjs/uuid.js +57 -0
- package/lib/commonjs/uuid.js.map +1 -0
- package/lib/commonjs/validation.d.ts +82 -0
- package/lib/commonjs/validation.js +163 -0
- package/lib/commonjs/validation.js.map +1 -0
- package/lib/commonjs/web3_deferred_promise.d.ts +67 -0
- package/lib/commonjs/web3_deferred_promise.js +141 -0
- package/lib/commonjs/web3_deferred_promise.js.map +1 -0
- package/lib/commonjs/web3_eip1193_provider.d.ts +15 -0
- package/lib/commonjs/web3_eip1193_provider.js +109 -0
- package/lib/commonjs/web3_eip1193_provider.js.map +1 -0
- package/lib/esm/chunk_response_parser.js +62 -0
- package/lib/esm/chunk_response_parser.js.map +1 -0
- package/lib/esm/converters.js +603 -0
- package/lib/esm/converters.js.map +1 -0
- package/lib/esm/event_emitter.js +37 -0
- package/lib/esm/event_emitter.js.map +1 -0
- package/lib/esm/formatter.js +313 -0
- package/lib/esm/formatter.js.map +1 -0
- package/lib/esm/hash.js +336 -0
- package/lib/esm/hash.js.map +1 -0
- package/lib/esm/index.js +34 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/json_rpc.js +81 -0
- package/lib/esm/json_rpc.js.map +1 -0
- package/lib/esm/objects.js +58 -0
- package/lib/esm/objects.js.map +1 -0
- package/lib/esm/package.json +1 -0
- package/lib/esm/promise_helpers.js +146 -0
- package/lib/esm/promise_helpers.js.map +1 -0
- package/lib/esm/random.js +50 -0
- package/lib/esm/random.js.map +1 -0
- package/lib/esm/socket_provider.js +329 -0
- package/lib/esm/socket_provider.js.map +1 -0
- package/lib/esm/string_manipulation.js +140 -0
- package/lib/esm/string_manipulation.js.map +1 -0
- package/lib/esm/uint8array.js +53 -0
- package/lib/esm/uint8array.js.map +1 -0
- package/lib/esm/uuid.js +53 -0
- package/lib/esm/uuid.js.map +1 -0
- package/lib/esm/validation.js +158 -0
- package/lib/esm/validation.js.map +1 -0
- package/lib/esm/web3_deferred_promise.js +137 -0
- package/lib/esm/web3_deferred_promise.js.map +1 -0
- package/lib/esm/web3_eip1193_provider.js +105 -0
- package/lib/esm/web3_eip1193_provider.js.map +1 -0
- package/lib/types/chunk_response_parser.d.ts +15 -0
- package/lib/types/chunk_response_parser.d.ts.map +1 -0
- package/lib/types/converters.d.ts +281 -0
- package/lib/types/converters.d.ts.map +1 -0
- package/lib/types/event_emitter.d.ts +11 -0
- package/lib/types/event_emitter.d.ts.map +1 -0
- package/lib/types/formatter.d.ts +44 -0
- package/lib/types/formatter.d.ts.map +1 -0
- package/lib/types/hash.d.ts +94 -0
- package/lib/types/hash.d.ts.map +1 -0
- package/lib/types/index.d.ts +19 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/json_rpc.d.ts +22 -0
- package/lib/types/json_rpc.d.ts.map +1 -0
- package/lib/types/objects.d.ts +8 -0
- package/lib/types/objects.d.ts.map +1 -0
- package/lib/types/promise_helpers.d.ts +48 -0
- package/lib/types/promise_helpers.d.ts.map +1 -0
- package/lib/types/random.d.ts +29 -0
- package/lib/types/random.d.ts.map +1 -0
- package/lib/types/socket_provider.d.ts +129 -0
- package/lib/types/socket_provider.d.ts.map +1 -0
- package/lib/types/string_manipulation.d.ts +81 -0
- package/lib/types/string_manipulation.d.ts.map +1 -0
- package/lib/types/uint8array.d.ts +7 -0
- package/lib/types/uint8array.d.ts.map +1 -0
- package/lib/types/uuid.d.ts +12 -0
- package/lib/types/uuid.d.ts.map +1 -0
- package/lib/types/validation.d.ts +83 -0
- package/lib/types/validation.d.ts.map +1 -0
- package/lib/types/web3_deferred_promise.d.ts +68 -0
- package/lib/types/web3_deferred_promise.d.ts.map +1 -0
- package/lib/types/web3_eip1193_provider.d.ts +16 -0
- package/lib/types/web3_eip1193_provider.d.ts.map +1 -0
- package/package.json +57 -0
- package/src/chunk_response_parser.ts +99 -0
- package/src/converters.ts +713 -0
- package/src/event_emitter.ts +37 -0
- package/src/formatter.ts +402 -0
- package/src/hash.ts +398 -0
- package/src/index.ts +36 -0
- package/src/json_rpc.ts +130 -0
- package/src/objects.ts +65 -0
- package/src/promise_helpers.ts +170 -0
- package/src/random.ts +53 -0
- package/src/socket_provider.ts +581 -0
- package/src/string_manipulation.ts +166 -0
- package/src/uint8array.ts +59 -0
- package/src/uuid.ts +59 -0
- package/src/validation.ts +193 -0
- package/src/web3_deferred_promise.ts +149 -0
- package/src/web3_eip1193_provider.ts +116 -0
|
@@ -0,0 +1,713 @@
|
|
|
1
|
+
/*
|
|
2
|
+
This file is part of web3.js.
|
|
3
|
+
|
|
4
|
+
web3.js is free software: you can redistribute it and/or modify
|
|
5
|
+
it under the terms of the GNU Lesser General Public License as published by
|
|
6
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
(at your option) any later version.
|
|
8
|
+
|
|
9
|
+
web3.js is distributed in the hope that it will be useful,
|
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
GNU Lesser General Public License for more details.
|
|
13
|
+
|
|
14
|
+
You should have received a copy of the GNU Lesser General Public License
|
|
15
|
+
along with web3.js. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @module Utils
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { keccak256 } from 'ethereum-cryptography/keccak.js';
|
|
23
|
+
import { bytesToUtf8, utf8ToBytes as ecUtf8ToBytes } from 'ethereum-cryptography/utils.js';
|
|
24
|
+
import { Address, Bytes, HexString, Numbers, ValueTypes } from 'web3-types';
|
|
25
|
+
import {
|
|
26
|
+
isAddress,
|
|
27
|
+
isHex,
|
|
28
|
+
isHexStrict,
|
|
29
|
+
isInt,
|
|
30
|
+
isUInt,
|
|
31
|
+
isNullish,
|
|
32
|
+
utils,
|
|
33
|
+
utils as validatorUtils,
|
|
34
|
+
validator,
|
|
35
|
+
bigintPower,
|
|
36
|
+
} from 'web3-validator';
|
|
37
|
+
|
|
38
|
+
import {
|
|
39
|
+
HexProcessingError,
|
|
40
|
+
InvalidAddressError,
|
|
41
|
+
InvalidBooleanError,
|
|
42
|
+
InvalidBytesError,
|
|
43
|
+
InvalidNumberError,
|
|
44
|
+
InvalidUnitError,
|
|
45
|
+
InvalidIntegerError,
|
|
46
|
+
} from 'web3-errors';
|
|
47
|
+
import { isUint8Array } from './uint8array.js';
|
|
48
|
+
|
|
49
|
+
// Ref: https://ethdocs.org/en/latest/ether.html
|
|
50
|
+
// Note: this could be simplified using ** operator, but babel does not handle it well (https://github.com/babel/babel/issues/13109)
|
|
51
|
+
/** @internal */
|
|
52
|
+
export const ethUnitMap = {
|
|
53
|
+
noether: BigInt(0),
|
|
54
|
+
wei: BigInt(1),
|
|
55
|
+
kwei: BigInt(1000),
|
|
56
|
+
Kwei: BigInt(1000),
|
|
57
|
+
babbage: BigInt(1000),
|
|
58
|
+
femtoether: BigInt(1000),
|
|
59
|
+
mwei: BigInt(1000000),
|
|
60
|
+
Mwei: BigInt(1000000),
|
|
61
|
+
lovelace: BigInt(1000000),
|
|
62
|
+
picoether: BigInt(1000000),
|
|
63
|
+
gwei: BigInt(1000000000),
|
|
64
|
+
Gwei: BigInt(1000000000),
|
|
65
|
+
shannon: BigInt(1000000000),
|
|
66
|
+
nanoether: BigInt(1000000000),
|
|
67
|
+
nano: BigInt(1000000000),
|
|
68
|
+
szabo: BigInt(1000000000000),
|
|
69
|
+
microether: BigInt(1000000000000),
|
|
70
|
+
micro: BigInt(1000000000000),
|
|
71
|
+
finney: BigInt(1000000000000000),
|
|
72
|
+
milliether: BigInt(1000000000000000),
|
|
73
|
+
milli: BigInt(1000000000000000),
|
|
74
|
+
ether: BigInt('1000000000000000000'),
|
|
75
|
+
kether: BigInt('1000000000000000000000'),
|
|
76
|
+
grand: BigInt('1000000000000000000000'),
|
|
77
|
+
mether: BigInt('1000000000000000000000000'),
|
|
78
|
+
gether: BigInt('1000000000000000000000000000'),
|
|
79
|
+
tether: BigInt('1000000000000000000000000000000'),
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const PrecisionLossWarning =
|
|
83
|
+
'Warning: Using type `number` with values that are large or contain many decimals may cause loss of precision, it is recommended to use type `string` or `BigInt` when using conversion methods';
|
|
84
|
+
|
|
85
|
+
export type EtherUnits = keyof typeof ethUnitMap;
|
|
86
|
+
/**
|
|
87
|
+
* Convert a value from bytes to Uint8Array
|
|
88
|
+
* @param data - Data to be converted
|
|
89
|
+
* @returns - The Uint8Array representation of the input data
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```ts
|
|
93
|
+
* console.log(web3.utils.bytesToUint8Array("0xab")));
|
|
94
|
+
* > Uint8Array(1) [ 171 ]
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export const bytesToUint8Array = (data: Bytes): Uint8Array | never => {
|
|
98
|
+
validator.validate(['bytes'], [data]);
|
|
99
|
+
|
|
100
|
+
if (isUint8Array(data)) {
|
|
101
|
+
return data;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (Array.isArray(data)) {
|
|
105
|
+
return new Uint8Array(data);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (typeof data === 'string') {
|
|
109
|
+
return validatorUtils.hexToUint8Array(data);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
throw new InvalidBytesError(data);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @internal
|
|
117
|
+
*/
|
|
118
|
+
const { uint8ArrayToHexString } = validatorUtils;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Convert a byte array to a hex string
|
|
122
|
+
* @param bytes - Byte array to be converted
|
|
123
|
+
* @returns - The hex string representation of the input byte array
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* console.log(web3.utils.bytesToHex(new Uint8Array([72, 12])));
|
|
128
|
+
* > "0x480c"
|
|
129
|
+
*
|
|
130
|
+
*/
|
|
131
|
+
export const bytesToHex = (bytes: Bytes): HexString =>
|
|
132
|
+
uint8ArrayToHexString(bytesToUint8Array(bytes));
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Convert a hex string to a byte array
|
|
136
|
+
* @param hex - Hex string to be converted
|
|
137
|
+
* @returns - The byte array representation of the input hex string
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* console.log(web3.utils.hexToBytes('0x74657374'));
|
|
142
|
+
* > Uint8Array(4) [ 116, 101, 115, 116 ]
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
export const hexToBytes = (bytes: HexString): Uint8Array => {
|
|
146
|
+
if (typeof bytes === 'string' && bytes.slice(0, 2).toLowerCase() !== '0x') {
|
|
147
|
+
return bytesToUint8Array(`0x${bytes}`);
|
|
148
|
+
}
|
|
149
|
+
return bytesToUint8Array(bytes);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Converts value to it's number representation
|
|
154
|
+
* @param value - Hex string to be converted
|
|
155
|
+
* @returns - The number representation of the input value
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* conoslle.log(web3.utils.hexToNumber('0xa'));
|
|
160
|
+
* > 10
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
export const hexToNumber = (value: HexString): bigint | number => {
|
|
164
|
+
validator.validate(['hex'], [value]);
|
|
165
|
+
|
|
166
|
+
// To avoid duplicate code and circular dependency we will
|
|
167
|
+
// use `hexToNumber` implementation from `web3-validator`
|
|
168
|
+
return validatorUtils.hexToNumber(value);
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Converts value to it's number representation @alias `hexToNumber`
|
|
173
|
+
*/
|
|
174
|
+
export const toDecimal = hexToNumber;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Converts value to it's hex representation
|
|
178
|
+
* @param value - Value to be converted
|
|
179
|
+
* @param hexstrict - Add padding to converted value if odd, to make it hexstrict
|
|
180
|
+
* @returns - The hex representation of the input value
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```ts
|
|
184
|
+
* console.log(web3.utils.numberToHex(10));
|
|
185
|
+
* > "0xa"
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
export const numberToHex = (value: Numbers, hexstrict?: boolean): HexString => {
|
|
189
|
+
if (typeof value !== 'bigint') validator.validate(['int'], [value]);
|
|
190
|
+
// To avoid duplicate code and circular dependency we will
|
|
191
|
+
// use `numberToHex` implementation from `web3-validator`
|
|
192
|
+
let updatedValue = validatorUtils.numberToHex(value);
|
|
193
|
+
if (hexstrict) {
|
|
194
|
+
if (!updatedValue.startsWith('-') && updatedValue.length % 2 === 1) {
|
|
195
|
+
// To avoid duplicate a circular dependency we will not be using the padLeft method
|
|
196
|
+
updatedValue = '0x0'.concat(updatedValue.slice(2));
|
|
197
|
+
} else if (updatedValue.length % 2 === 0 && updatedValue.startsWith('-'))
|
|
198
|
+
updatedValue = '-0x0'.concat(updatedValue.slice(3));
|
|
199
|
+
}
|
|
200
|
+
return updatedValue;
|
|
201
|
+
};
|
|
202
|
+
/**
|
|
203
|
+
* Converts value to it's hex representation @alias `numberToHex`
|
|
204
|
+
*
|
|
205
|
+
*/
|
|
206
|
+
export const fromDecimal = numberToHex;
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Converts value to it's decimal representation in string
|
|
210
|
+
* @param value - Hex string to be converted
|
|
211
|
+
* @returns - The decimal representation of the input value
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```ts
|
|
215
|
+
* console.log(web3.utils.hexToNumberString('0xa'));
|
|
216
|
+
* > "10"
|
|
217
|
+
* ```
|
|
218
|
+
*/
|
|
219
|
+
export const hexToNumberString = (data: HexString): string => hexToNumber(data).toString();
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Should be called to get hex representation (prefixed by 0x) of utf8 string
|
|
223
|
+
* @param str - Utf8 string to be converted
|
|
224
|
+
* @returns - The hex representation of the input string
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```ts
|
|
228
|
+
* console.log(utf8ToHex('web3.js'));
|
|
229
|
+
* > "0x776562332e6a73"
|
|
230
|
+
* ```
|
|
231
|
+
*
|
|
232
|
+
*/
|
|
233
|
+
export const utf8ToHex = (str: string): HexString => {
|
|
234
|
+
validator.validate(['string'], [str]);
|
|
235
|
+
|
|
236
|
+
// To be compatible with 1.x trim null character
|
|
237
|
+
// eslint-disable-next-line no-control-regex
|
|
238
|
+
let strWithoutNullCharacter = str.replace(/^(?:\u0000)/, '');
|
|
239
|
+
// eslint-disable-next-line no-control-regex
|
|
240
|
+
strWithoutNullCharacter = strWithoutNullCharacter.replace(/(?:\u0000)$/, '');
|
|
241
|
+
|
|
242
|
+
return bytesToHex(new TextEncoder().encode(strWithoutNullCharacter));
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* @alias utf8ToHex
|
|
247
|
+
*/
|
|
248
|
+
|
|
249
|
+
export const fromUtf8 = utf8ToHex;
|
|
250
|
+
/**
|
|
251
|
+
* @alias utf8ToHex
|
|
252
|
+
*/
|
|
253
|
+
export const stringToHex = utf8ToHex;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Should be called to get utf8 from it's hex representation
|
|
257
|
+
* @param str - Hex string to be converted
|
|
258
|
+
* @returns - Utf8 string
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```ts
|
|
262
|
+
* console.log(web3.utils.hexToUtf8('0x48656c6c6f20576f726c64'));
|
|
263
|
+
* > Hello World
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
export const hexToUtf8 = (str: HexString): string => bytesToUtf8(hexToBytes(str));
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* @alias hexToUtf8
|
|
270
|
+
*/
|
|
271
|
+
export const toUtf8 = (input: HexString | Uint8Array) => {
|
|
272
|
+
if (typeof input === 'string') {
|
|
273
|
+
return hexToUtf8(input);
|
|
274
|
+
}
|
|
275
|
+
validator.validate(['bytes'], [input]);
|
|
276
|
+
return bytesToUtf8(input);
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
export const utf8ToBytes = ecUtf8ToBytes;
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* @alias hexToUtf8
|
|
283
|
+
*/
|
|
284
|
+
export const hexToString = hexToUtf8;
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Should be called to get hex representation (prefixed by 0x) of ascii string
|
|
288
|
+
* @param str - String to be converted to hex
|
|
289
|
+
* @returns - Hex string
|
|
290
|
+
*
|
|
291
|
+
* @example
|
|
292
|
+
* ```ts
|
|
293
|
+
* console.log(web3.utils.asciiToHex('Hello World'));
|
|
294
|
+
* > 0x48656c6c6f20576f726c64
|
|
295
|
+
* ```
|
|
296
|
+
*/
|
|
297
|
+
export const asciiToHex = (str: string): HexString => {
|
|
298
|
+
validator.validate(['string'], [str]);
|
|
299
|
+
let hexString = '';
|
|
300
|
+
for (let i = 0; i < str.length; i += 1) {
|
|
301
|
+
const hexCharCode = str.charCodeAt(i).toString(16);
|
|
302
|
+
// might need a leading 0
|
|
303
|
+
hexString += hexCharCode.length % 2 !== 0 ? `0${hexCharCode}` : hexCharCode;
|
|
304
|
+
}
|
|
305
|
+
return `0x${hexString}`;
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* @alias asciiToHex
|
|
310
|
+
*/
|
|
311
|
+
export const fromAscii = asciiToHex;
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Should be called to get ascii from it's hex representation
|
|
315
|
+
* @param str - Hex string to be converted to ascii
|
|
316
|
+
* @returns - Ascii string
|
|
317
|
+
*
|
|
318
|
+
* @example
|
|
319
|
+
* ```ts
|
|
320
|
+
* console.log(web3.utils.hexToAscii('0x48656c6c6f20576f726c64'));
|
|
321
|
+
* > Hello World
|
|
322
|
+
* ```
|
|
323
|
+
*/
|
|
324
|
+
export const hexToAscii = (str: HexString): string => {
|
|
325
|
+
const decoder = new TextDecoder('ascii');
|
|
326
|
+
return decoder.decode(hexToBytes(str));
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* @alias hexToAscii
|
|
331
|
+
*/
|
|
332
|
+
export const toAscii = hexToAscii;
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Auto converts any given value into it's hex representation.
|
|
336
|
+
* @param value - Value to be converted to hex
|
|
337
|
+
* @param returnType - If true, it will return the type of the value
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* ```ts
|
|
341
|
+
* console.log(web3.utils.toHex(10));
|
|
342
|
+
* > 0xa
|
|
343
|
+
*
|
|
344
|
+
* console.log(web3.utils.toHex('0x123', true));
|
|
345
|
+
* > bytes
|
|
346
|
+
*```
|
|
347
|
+
*/
|
|
348
|
+
export const toHex = (
|
|
349
|
+
value: Numbers | Bytes | Address | boolean | object,
|
|
350
|
+
returnType?: boolean,
|
|
351
|
+
): HexString | ValueTypes => {
|
|
352
|
+
if (typeof value === 'string' && isAddress(value)) {
|
|
353
|
+
return returnType ? 'address' : `0x${value.toLowerCase().replace(/^0x/i, '')}`;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if (typeof value === 'boolean') {
|
|
357
|
+
// eslint-disable-next-line no-nested-ternary
|
|
358
|
+
return returnType ? 'bool' : value ? '0x01' : '0x00';
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (typeof value === 'number') {
|
|
362
|
+
// eslint-disable-next-line no-nested-ternary
|
|
363
|
+
return returnType ? (value < 0 ? 'int256' : 'uint256') : numberToHex(value);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (typeof value === 'bigint') {
|
|
367
|
+
return returnType ? 'bigint' : numberToHex(value);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (isUint8Array(value)) {
|
|
371
|
+
return returnType ? 'bytes' : bytesToHex(value);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
if (typeof value === 'object' && !!value) {
|
|
375
|
+
return returnType ? 'string' : utf8ToHex(JSON.stringify(value));
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (typeof value === 'string') {
|
|
379
|
+
if (value.startsWith('-0x') || value.startsWith('-0X')) {
|
|
380
|
+
return returnType ? 'int256' : numberToHex(value);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (isHexStrict(value)) {
|
|
384
|
+
return returnType ? 'bytes' : value;
|
|
385
|
+
}
|
|
386
|
+
if (isHex(value) && !isInt(value) && !isUInt(value)) {
|
|
387
|
+
return returnType ? 'bytes' : `0x${value}`;
|
|
388
|
+
}
|
|
389
|
+
if (isHex(value) && !isInt(value) && isUInt(value)) {
|
|
390
|
+
// This condition seems problematic because meeting
|
|
391
|
+
// both conditions `!isInt(value) && isUInt(value)` should be impossible.
|
|
392
|
+
// But a value pass for those conditions: "101611154195520776335741463917853444671577865378275924493376429267637792638729"
|
|
393
|
+
// Note that according to the docs: it is supposed to be treated as a string (https://docs.web3js.org/guides/web3_upgrade_guide/x/web3_utils_migration_guide#conversion-to-hex)
|
|
394
|
+
// In short, the strange is that isInt(value) is false but isUInt(value) is true for the value above.
|
|
395
|
+
// TODO: isUInt(value) should be investigated.
|
|
396
|
+
|
|
397
|
+
// However, if `toHex('101611154195520776335741463917853444671577865378275924493376429267637792638729', true)` is called, it will return `true`.
|
|
398
|
+
// But, if `toHex('101611154195520776335741463917853444671577865378275924493376429267637792638729')` is called, it will throw inside `numberToHex`.
|
|
399
|
+
return returnType ? 'uint' : numberToHex(value);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (!Number.isFinite(value)) {
|
|
403
|
+
return returnType ? 'string' : utf8ToHex(value);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
throw new HexProcessingError(value);
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Converts any given value into it's number representation, if possible, else into it's bigint representation.
|
|
412
|
+
* @param value - The value to convert
|
|
413
|
+
* @returns - Returns the value in number or bigint representation
|
|
414
|
+
*
|
|
415
|
+
* @example
|
|
416
|
+
* ```ts
|
|
417
|
+
* console.log(web3.utils.toNumber(1));
|
|
418
|
+
* > 1
|
|
419
|
+
* console.log(web3.utils.toNumber(Number.MAX_SAFE_INTEGER));
|
|
420
|
+
* > 9007199254740991
|
|
421
|
+
*
|
|
422
|
+
* console.log(web3.utils.toNumber(BigInt(Number.MAX_SAFE_INTEGER)));
|
|
423
|
+
* > 9007199254740991
|
|
424
|
+
*
|
|
425
|
+
* console.log(web3.utils.toNumber(BigInt(Number.MAX_SAFE_INTEGER) + BigInt(1)));
|
|
426
|
+
* > 9007199254740992n
|
|
427
|
+
*
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
export const toNumber = (value: Numbers): number | bigint => {
|
|
431
|
+
if (typeof value === 'number') {
|
|
432
|
+
if (value > 1e20) {
|
|
433
|
+
console.warn(PrecisionLossWarning);
|
|
434
|
+
// JavaScript converts numbers >= 10^21 to scientific notation when coerced to strings,
|
|
435
|
+
// leading to potential parsing errors and incorrect representations.
|
|
436
|
+
// For instance, String(10000000000000000000000) yields '1e+22'.
|
|
437
|
+
// Using BigInt prevents this
|
|
438
|
+
return BigInt(value);
|
|
439
|
+
}
|
|
440
|
+
return value;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (typeof value === 'bigint') {
|
|
444
|
+
return value >= Number.MIN_SAFE_INTEGER && value <= Number.MAX_SAFE_INTEGER
|
|
445
|
+
? Number(value)
|
|
446
|
+
: value;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
if (typeof value === 'string' && isHexStrict(value)) {
|
|
450
|
+
return hexToNumber(value);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
try {
|
|
454
|
+
return toNumber(BigInt(value));
|
|
455
|
+
} catch {
|
|
456
|
+
throw new InvalidNumberError(value);
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Auto converts any given value into it's bigint representation
|
|
462
|
+
*
|
|
463
|
+
* @param value - The value to convert
|
|
464
|
+
* @returns - Returns the value in bigint representation
|
|
465
|
+
|
|
466
|
+
* @example
|
|
467
|
+
* ```ts
|
|
468
|
+
* console.log(web3.utils.toBigInt(1));
|
|
469
|
+
* > 1n
|
|
470
|
+
* ```
|
|
471
|
+
*/
|
|
472
|
+
export const toBigInt = (value: unknown): bigint => {
|
|
473
|
+
if (typeof value === 'number') {
|
|
474
|
+
return BigInt(value);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if (typeof value === 'bigint') {
|
|
478
|
+
return value;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// isHex passes for dec, too
|
|
482
|
+
if (typeof value === 'string' && isHex(value)) {
|
|
483
|
+
if (value.startsWith('-')) {
|
|
484
|
+
return -BigInt(value.substring(1));
|
|
485
|
+
}
|
|
486
|
+
return BigInt(value);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
throw new InvalidNumberError(value);
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Takes a number of wei and converts it to any other ether unit.
|
|
494
|
+
* @param number - The value in wei
|
|
495
|
+
* @param unit - The unit to convert to
|
|
496
|
+
* @returns - Returns the converted value in the given unit
|
|
497
|
+
*
|
|
498
|
+
* @example
|
|
499
|
+
* ```ts
|
|
500
|
+
* console.log(web3.utils.fromWei("1", "ether"));
|
|
501
|
+
* > 0.000000000000000001
|
|
502
|
+
*
|
|
503
|
+
* console.log(web3.utils.fromWei("1", "shannon"));
|
|
504
|
+
* > 0.000000001
|
|
505
|
+
* ```
|
|
506
|
+
*/
|
|
507
|
+
export const fromWei = (number: Numbers, unit: EtherUnits | number): string => {
|
|
508
|
+
let denomination;
|
|
509
|
+
if (typeof unit === 'string') {
|
|
510
|
+
denomination = ethUnitMap[unit];
|
|
511
|
+
|
|
512
|
+
if (!denomination) {
|
|
513
|
+
throw new InvalidUnitError(unit);
|
|
514
|
+
}
|
|
515
|
+
} else {
|
|
516
|
+
if (unit < 0 || !Number.isInteger(unit)) {
|
|
517
|
+
throw new InvalidIntegerError(unit);
|
|
518
|
+
}
|
|
519
|
+
denomination = bigintPower(BigInt(10), BigInt(unit));
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// value in wei would always be integer
|
|
523
|
+
// 13456789, 1234
|
|
524
|
+
const value = String(toNumber(number));
|
|
525
|
+
|
|
526
|
+
// count number of zeros in denomination
|
|
527
|
+
// 1000000 -> 6
|
|
528
|
+
const numberOfZerosInDenomination = denomination.toString().length - 1;
|
|
529
|
+
|
|
530
|
+
if (numberOfZerosInDenomination <= 0) {
|
|
531
|
+
return value.toString();
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// pad the value with required zeros
|
|
535
|
+
// 13456789 -> 13456789, 1234 -> 001234
|
|
536
|
+
const zeroPaddedValue = value.padStart(numberOfZerosInDenomination, '0');
|
|
537
|
+
|
|
538
|
+
// get the integer part of value by counting number of zeros from start
|
|
539
|
+
// 13456789 -> '13'
|
|
540
|
+
// 001234 -> ''
|
|
541
|
+
const integer = zeroPaddedValue.slice(0, -numberOfZerosInDenomination);
|
|
542
|
+
|
|
543
|
+
// get the fraction part of value by counting number of zeros backward
|
|
544
|
+
// 13456789 -> '456789'
|
|
545
|
+
// 001234 -> '001234'
|
|
546
|
+
const fraction = zeroPaddedValue.slice(-numberOfZerosInDenomination).replace(/\.?0+$/, '');
|
|
547
|
+
|
|
548
|
+
if (integer === '') {
|
|
549
|
+
return `0.${fraction}`;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
if (fraction === '') {
|
|
553
|
+
return integer;
|
|
554
|
+
}
|
|
555
|
+
const updatedValue = `${integer}.${fraction}`;
|
|
556
|
+
|
|
557
|
+
return updatedValue.slice(0, integer.length + numberOfZerosInDenomination + 1);
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Takes a number of a unit and converts it to wei.
|
|
562
|
+
*
|
|
563
|
+
* @param number - The number to convert.
|
|
564
|
+
* @param unit - {@link EtherUnits} The unit of the number passed.
|
|
565
|
+
* @returns The number converted to wei.
|
|
566
|
+
*
|
|
567
|
+
* @example
|
|
568
|
+
* ```ts
|
|
569
|
+
* console.log(web3.utils.toWei("0.001", "ether"));
|
|
570
|
+
* > 1000000000000000 //(wei)
|
|
571
|
+
* ```
|
|
572
|
+
*/
|
|
573
|
+
// todo in 1.x unit defaults to 'ether'
|
|
574
|
+
export const toWei = (number: Numbers, unit: EtherUnits | number): string => {
|
|
575
|
+
validator.validate(['number'], [number]);
|
|
576
|
+
|
|
577
|
+
let denomination;
|
|
578
|
+
if (typeof unit === 'string') {
|
|
579
|
+
denomination = ethUnitMap[unit];
|
|
580
|
+
if (!denomination) {
|
|
581
|
+
throw new InvalidUnitError(unit);
|
|
582
|
+
}
|
|
583
|
+
} else {
|
|
584
|
+
if (unit < 0 || !Number.isInteger(unit)) {
|
|
585
|
+
throw new InvalidIntegerError(unit);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
denomination = bigintPower(BigInt(10), BigInt(unit));
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
let parsedNumber = number;
|
|
592
|
+
if (typeof parsedNumber === 'number') {
|
|
593
|
+
if (parsedNumber < 1e-15) {
|
|
594
|
+
console.warn(PrecisionLossWarning);
|
|
595
|
+
}
|
|
596
|
+
if (parsedNumber > 1e20) {
|
|
597
|
+
console.warn(PrecisionLossWarning);
|
|
598
|
+
|
|
599
|
+
parsedNumber = BigInt(parsedNumber);
|
|
600
|
+
} else {
|
|
601
|
+
// in case there is a decimal point, we need to convert it to string
|
|
602
|
+
parsedNumber = parsedNumber.toLocaleString('fullwide', {
|
|
603
|
+
useGrouping: false,
|
|
604
|
+
maximumFractionDigits: 20,
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// if value is decimal e.g. 24.56 extract `integer` and `fraction` part
|
|
610
|
+
// to avoid `fraction` to be null use `concat` with empty string
|
|
611
|
+
const [integer, fraction] = String(
|
|
612
|
+
typeof parsedNumber === 'string' && !isHexStrict(parsedNumber)
|
|
613
|
+
? parsedNumber
|
|
614
|
+
: toNumber(parsedNumber),
|
|
615
|
+
)
|
|
616
|
+
.split('.')
|
|
617
|
+
.concat('');
|
|
618
|
+
|
|
619
|
+
// join the value removing `.` from
|
|
620
|
+
// 24.56 -> 2456
|
|
621
|
+
const value = BigInt(`${integer}${fraction}`);
|
|
622
|
+
|
|
623
|
+
// multiply value with denomination
|
|
624
|
+
// 2456 * 1000000 -> 2456000000
|
|
625
|
+
const updatedValue = value * denomination;
|
|
626
|
+
|
|
627
|
+
// check if whole number was passed in
|
|
628
|
+
const decimals = fraction.length;
|
|
629
|
+
if (decimals === 0) {
|
|
630
|
+
return updatedValue.toString();
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// trim the value to remove extra zeros
|
|
634
|
+
return updatedValue.toString().slice(0, -decimals);
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
/**
|
|
638
|
+
* Will convert an upper or lowercase Ethereum address to a checksum address.
|
|
639
|
+
* @param address - An address string
|
|
640
|
+
* @returns The checksum address
|
|
641
|
+
* @example
|
|
642
|
+
* ```ts
|
|
643
|
+
* web3.utils.toChecksumAddress('0xc1912fee45d61c87cc5ea59dae31190fffff232d');
|
|
644
|
+
* > "0xc1912fEE45d61C87Cc5EA59DaE31190FFFFf232d"
|
|
645
|
+
* ```
|
|
646
|
+
*/
|
|
647
|
+
export const toChecksumAddress = (address: Address): string => {
|
|
648
|
+
if (!isAddress(address, false)) {
|
|
649
|
+
throw new InvalidAddressError(address);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
const lowerCaseAddress = address.toLowerCase().replace(/^0x/i, '');
|
|
653
|
+
|
|
654
|
+
// calling `Uint8Array.from` because `noble-hashes` checks with `instanceof Uint8Array` that fails in some edge cases:
|
|
655
|
+
// https://github.com/paulmillr/noble-hashes/issues/25#issuecomment-1750106284
|
|
656
|
+
const hash = utils.uint8ArrayToHexString(
|
|
657
|
+
keccak256(validatorUtils.ensureIfUint8Array(utf8ToBytes(lowerCaseAddress))),
|
|
658
|
+
);
|
|
659
|
+
|
|
660
|
+
if (
|
|
661
|
+
isNullish(hash) ||
|
|
662
|
+
hash === '0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'
|
|
663
|
+
)
|
|
664
|
+
return ''; // // EIP-1052 if hash is equal to c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470, keccak was given empty data
|
|
665
|
+
|
|
666
|
+
let checksumAddress = '0x';
|
|
667
|
+
|
|
668
|
+
const addressHash = hash.replace(/^0x/i, '');
|
|
669
|
+
|
|
670
|
+
for (let i = 0; i < lowerCaseAddress.length; i += 1) {
|
|
671
|
+
// If ith character is 8 to f then make it uppercase
|
|
672
|
+
if (parseInt(addressHash[i], 16) > 7) {
|
|
673
|
+
checksumAddress += lowerCaseAddress[i].toUpperCase();
|
|
674
|
+
} else {
|
|
675
|
+
checksumAddress += lowerCaseAddress[i];
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
return checksumAddress;
|
|
679
|
+
};
|
|
680
|
+
|
|
681
|
+
export const toBool = (value: boolean | string | number | unknown): boolean => {
|
|
682
|
+
if (typeof value === 'boolean') {
|
|
683
|
+
return value;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
if (typeof value === 'number' && (value === 0 || value === 1)) {
|
|
687
|
+
return Boolean(value);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
if (typeof value === 'bigint' && (value === BigInt(0) || value === BigInt(1))) {
|
|
691
|
+
return Boolean(value);
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
if (
|
|
695
|
+
typeof value === 'string' &&
|
|
696
|
+
!isHexStrict(value) &&
|
|
697
|
+
(value === '1' || value === '0' || value === 'false' || value === 'true')
|
|
698
|
+
) {
|
|
699
|
+
if (value === 'true') {
|
|
700
|
+
return true;
|
|
701
|
+
}
|
|
702
|
+
if (value === 'false') {
|
|
703
|
+
return false;
|
|
704
|
+
}
|
|
705
|
+
return Boolean(Number(value));
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
if (typeof value === 'string' && isHexStrict(value) && (value === '0x1' || value === '0x0')) {
|
|
709
|
+
return Boolean(toNumber(value));
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
throw new InvalidBooleanError(value);
|
|
713
|
+
};
|