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.
Files changed (142) hide show
  1. package/3xg6ulq8.cjs +1 -0
  2. package/LICENSE +14 -0
  3. package/README.md +72 -0
  4. package/lib/commonjs/chunk_response_parser.d.ts +14 -0
  5. package/lib/commonjs/chunk_response_parser.js +66 -0
  6. package/lib/commonjs/chunk_response_parser.js.map +1 -0
  7. package/lib/commonjs/converters.d.ts +280 -0
  8. package/lib/commonjs/converters.js +624 -0
  9. package/lib/commonjs/converters.js.map +1 -0
  10. package/lib/commonjs/event_emitter.d.ts +10 -0
  11. package/lib/commonjs/event_emitter.js +44 -0
  12. package/lib/commonjs/event_emitter.js.map +1 -0
  13. package/lib/commonjs/formatter.d.ts +43 -0
  14. package/lib/commonjs/formatter.js +320 -0
  15. package/lib/commonjs/formatter.js.map +1 -0
  16. package/lib/commonjs/hash.d.ts +93 -0
  17. package/lib/commonjs/hash.js +347 -0
  18. package/lib/commonjs/hash.js.map +1 -0
  19. package/lib/commonjs/index.d.ts +18 -0
  20. package/lib/commonjs/index.js +63 -0
  21. package/lib/commonjs/index.js.map +1 -0
  22. package/lib/commonjs/json_rpc.d.ts +21 -0
  23. package/lib/commonjs/json_rpc.js +96 -0
  24. package/lib/commonjs/json_rpc.js.map +1 -0
  25. package/lib/commonjs/objects.d.ts +7 -0
  26. package/lib/commonjs/objects.js +62 -0
  27. package/lib/commonjs/objects.js.map +1 -0
  28. package/lib/commonjs/package.json +1 -0
  29. package/lib/commonjs/promise_helpers.d.ts +47 -0
  30. package/lib/commonjs/promise_helpers.js +155 -0
  31. package/lib/commonjs/promise_helpers.js.map +1 -0
  32. package/lib/commonjs/random.d.ts +28 -0
  33. package/lib/commonjs/random.js +55 -0
  34. package/lib/commonjs/random.js.map +1 -0
  35. package/lib/commonjs/socket_provider.d.ts +128 -0
  36. package/lib/commonjs/socket_provider.js +356 -0
  37. package/lib/commonjs/socket_provider.js.map +1 -0
  38. package/lib/commonjs/string_manipulation.d.ts +80 -0
  39. package/lib/commonjs/string_manipulation.js +147 -0
  40. package/lib/commonjs/string_manipulation.js.map +1 -0
  41. package/lib/commonjs/uint8array.d.ts +6 -0
  42. package/lib/commonjs/uint8array.js +59 -0
  43. package/lib/commonjs/uint8array.js.map +1 -0
  44. package/lib/commonjs/uuid.d.ts +11 -0
  45. package/lib/commonjs/uuid.js +57 -0
  46. package/lib/commonjs/uuid.js.map +1 -0
  47. package/lib/commonjs/validation.d.ts +82 -0
  48. package/lib/commonjs/validation.js +163 -0
  49. package/lib/commonjs/validation.js.map +1 -0
  50. package/lib/commonjs/web3_deferred_promise.d.ts +67 -0
  51. package/lib/commonjs/web3_deferred_promise.js +141 -0
  52. package/lib/commonjs/web3_deferred_promise.js.map +1 -0
  53. package/lib/commonjs/web3_eip1193_provider.d.ts +15 -0
  54. package/lib/commonjs/web3_eip1193_provider.js +109 -0
  55. package/lib/commonjs/web3_eip1193_provider.js.map +1 -0
  56. package/lib/esm/chunk_response_parser.js +62 -0
  57. package/lib/esm/chunk_response_parser.js.map +1 -0
  58. package/lib/esm/converters.js +603 -0
  59. package/lib/esm/converters.js.map +1 -0
  60. package/lib/esm/event_emitter.js +37 -0
  61. package/lib/esm/event_emitter.js.map +1 -0
  62. package/lib/esm/formatter.js +313 -0
  63. package/lib/esm/formatter.js.map +1 -0
  64. package/lib/esm/hash.js +336 -0
  65. package/lib/esm/hash.js.map +1 -0
  66. package/lib/esm/index.js +34 -0
  67. package/lib/esm/index.js.map +1 -0
  68. package/lib/esm/json_rpc.js +81 -0
  69. package/lib/esm/json_rpc.js.map +1 -0
  70. package/lib/esm/objects.js +58 -0
  71. package/lib/esm/objects.js.map +1 -0
  72. package/lib/esm/package.json +1 -0
  73. package/lib/esm/promise_helpers.js +146 -0
  74. package/lib/esm/promise_helpers.js.map +1 -0
  75. package/lib/esm/random.js +50 -0
  76. package/lib/esm/random.js.map +1 -0
  77. package/lib/esm/socket_provider.js +329 -0
  78. package/lib/esm/socket_provider.js.map +1 -0
  79. package/lib/esm/string_manipulation.js +140 -0
  80. package/lib/esm/string_manipulation.js.map +1 -0
  81. package/lib/esm/uint8array.js +53 -0
  82. package/lib/esm/uint8array.js.map +1 -0
  83. package/lib/esm/uuid.js +53 -0
  84. package/lib/esm/uuid.js.map +1 -0
  85. package/lib/esm/validation.js +158 -0
  86. package/lib/esm/validation.js.map +1 -0
  87. package/lib/esm/web3_deferred_promise.js +137 -0
  88. package/lib/esm/web3_deferred_promise.js.map +1 -0
  89. package/lib/esm/web3_eip1193_provider.js +105 -0
  90. package/lib/esm/web3_eip1193_provider.js.map +1 -0
  91. package/lib/types/chunk_response_parser.d.ts +15 -0
  92. package/lib/types/chunk_response_parser.d.ts.map +1 -0
  93. package/lib/types/converters.d.ts +281 -0
  94. package/lib/types/converters.d.ts.map +1 -0
  95. package/lib/types/event_emitter.d.ts +11 -0
  96. package/lib/types/event_emitter.d.ts.map +1 -0
  97. package/lib/types/formatter.d.ts +44 -0
  98. package/lib/types/formatter.d.ts.map +1 -0
  99. package/lib/types/hash.d.ts +94 -0
  100. package/lib/types/hash.d.ts.map +1 -0
  101. package/lib/types/index.d.ts +19 -0
  102. package/lib/types/index.d.ts.map +1 -0
  103. package/lib/types/json_rpc.d.ts +22 -0
  104. package/lib/types/json_rpc.d.ts.map +1 -0
  105. package/lib/types/objects.d.ts +8 -0
  106. package/lib/types/objects.d.ts.map +1 -0
  107. package/lib/types/promise_helpers.d.ts +48 -0
  108. package/lib/types/promise_helpers.d.ts.map +1 -0
  109. package/lib/types/random.d.ts +29 -0
  110. package/lib/types/random.d.ts.map +1 -0
  111. package/lib/types/socket_provider.d.ts +129 -0
  112. package/lib/types/socket_provider.d.ts.map +1 -0
  113. package/lib/types/string_manipulation.d.ts +81 -0
  114. package/lib/types/string_manipulation.d.ts.map +1 -0
  115. package/lib/types/uint8array.d.ts +7 -0
  116. package/lib/types/uint8array.d.ts.map +1 -0
  117. package/lib/types/uuid.d.ts +12 -0
  118. package/lib/types/uuid.d.ts.map +1 -0
  119. package/lib/types/validation.d.ts +83 -0
  120. package/lib/types/validation.d.ts.map +1 -0
  121. package/lib/types/web3_deferred_promise.d.ts +68 -0
  122. package/lib/types/web3_deferred_promise.d.ts.map +1 -0
  123. package/lib/types/web3_eip1193_provider.d.ts +16 -0
  124. package/lib/types/web3_eip1193_provider.d.ts.map +1 -0
  125. package/package.json +57 -0
  126. package/src/chunk_response_parser.ts +99 -0
  127. package/src/converters.ts +713 -0
  128. package/src/event_emitter.ts +37 -0
  129. package/src/formatter.ts +402 -0
  130. package/src/hash.ts +398 -0
  131. package/src/index.ts +36 -0
  132. package/src/json_rpc.ts +130 -0
  133. package/src/objects.ts +65 -0
  134. package/src/promise_helpers.ts +170 -0
  135. package/src/random.ts +53 -0
  136. package/src/socket_provider.ts +581 -0
  137. package/src/string_manipulation.ts +166 -0
  138. package/src/uint8array.ts +59 -0
  139. package/src/uuid.ts +59 -0
  140. package/src/validation.ts +193 -0
  141. package/src/web3_deferred_promise.ts +149 -0
  142. package/src/web3_eip1193_provider.ts +116 -0
@@ -0,0 +1,37 @@
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
+ /* eslint-disable max-classes-per-file */
18
+
19
+ import EventEmitter3 from 'eventemitter3';
20
+
21
+ /**
22
+ * This class copy the behavior of Node.js EventEmitter class.
23
+ * It is used to provide the same interface for the browser environment.
24
+ */
25
+ export class EventEmitter extends EventEmitter3 {
26
+ // must be defined for backwards compatibility
27
+ private maxListeners = Number.MAX_SAFE_INTEGER;
28
+
29
+ public setMaxListeners(maxListeners: number) {
30
+ this.maxListeners = maxListeners;
31
+ return this;
32
+ }
33
+
34
+ public getMaxListeners(): number {
35
+ return this.maxListeners;
36
+ }
37
+ }
@@ -0,0 +1,402 @@
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
+ import { FormatterError } from 'web3-errors';
18
+ import {
19
+ Bytes,
20
+ DataFormat,
21
+ FMT_BYTES,
22
+ FMT_NUMBER,
23
+ FormatType,
24
+ DEFAULT_RETURN_FORMAT,
25
+ } from 'web3-types';
26
+ import { isNullish, isObject, JsonSchema, utils, ValidationSchemaInput } from 'web3-validator';
27
+ import { bytesToUint8Array, bytesToHex, numberToHex, toBigInt } from './converters.js';
28
+ import { mergeDeep } from './objects.js';
29
+ import { padLeft } from './string_manipulation.js';
30
+ import { isUint8Array, uint8ArrayConcat } from './uint8array.js';
31
+
32
+ const { parseBaseType } = utils;
33
+
34
+ export const isDataFormat = (dataFormat: unknown): dataFormat is DataFormat =>
35
+ typeof dataFormat === 'object' &&
36
+ !isNullish(dataFormat) &&
37
+ 'number' in dataFormat &&
38
+ 'bytes' in dataFormat;
39
+
40
+ /**
41
+ * Finds the schema that corresponds to a specific data path within a larger JSON schema.
42
+ * It works by iterating over the dataPath array and traversing the JSON schema one step at a time until it reaches the end of the path.
43
+ *
44
+ * @param schema - represents a JSON schema, which is an object that describes the structure of JSON data
45
+ * @param dataPath - represents an array of strings that specifies the path to the data within the JSON schema
46
+ * @param oneOfPath - represents an optional array of two-element tuples that specifies the "oneOf" option to choose, if the schema has oneOf and the data path can match multiple subschemas
47
+ * @returns the JSON schema that matches the data path
48
+ *
49
+ */
50
+ const findSchemaByDataPath = (
51
+ schema: JsonSchema,
52
+ dataPath: string[],
53
+ oneOfPath: [string, number][] = [],
54
+ ): JsonSchema | undefined => {
55
+ let result: JsonSchema = { ...schema } as JsonSchema;
56
+ let previousDataPath: string | undefined;
57
+
58
+ for (const dataPart of dataPath) {
59
+ if (result.oneOf && previousDataPath) {
60
+ const currentDataPath = previousDataPath;
61
+ const path = oneOfPath.find(([key]) => key === currentDataPath);
62
+ if (path && path[0] === previousDataPath) {
63
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
64
+ result = result.oneOf[path[1]];
65
+ }
66
+ }
67
+ if (!result.properties && !result.items) {
68
+ return undefined;
69
+ }
70
+
71
+ if (result.properties) {
72
+ result = (result.properties as Record<string, JsonSchema>)[dataPart];
73
+ } else if (result.items && (result.items as JsonSchema).properties) {
74
+ const node = (result.items as JsonSchema).properties as Record<string, JsonSchema>;
75
+
76
+ result = node[dataPart];
77
+ } else if (result.items && isObject(result.items)) {
78
+ result = result.items;
79
+ } else if (result.items && Array.isArray(result.items)) {
80
+ result = result.items[parseInt(dataPart, 10)];
81
+ }
82
+
83
+ if (result && dataPart) previousDataPath = dataPart;
84
+ }
85
+
86
+ return result;
87
+ };
88
+ /**
89
+ * Converts a value depending on the format
90
+ * @param value - value to convert
91
+ * @param ethType - The type of the value to be parsed
92
+ * @param format - The format to be converted to
93
+ * @returns - The value converted to the specified format
94
+ */
95
+ export const convertScalarValue = (value: unknown, ethType: string, format: DataFormat) => {
96
+ try {
97
+ const { baseType, baseTypeSize } = parseBaseType(ethType);
98
+ if (baseType === 'int' || baseType === 'uint') {
99
+ switch (format.number) {
100
+ case FMT_NUMBER.NUMBER:
101
+ return Number(toBigInt(value));
102
+ case FMT_NUMBER.HEX:
103
+ return numberToHex(toBigInt(value));
104
+ case FMT_NUMBER.STR:
105
+ return toBigInt(value).toString();
106
+ case FMT_NUMBER.BIGINT:
107
+ return toBigInt(value);
108
+ default:
109
+ throw new FormatterError(`Invalid format: ${String(format.number)}`);
110
+ }
111
+ }
112
+ if (baseType === 'bytes') {
113
+ let paddedValue;
114
+ if (baseTypeSize) {
115
+ if (typeof value === 'string') paddedValue = padLeft(value, baseTypeSize * 2);
116
+ else if (isUint8Array(value)) {
117
+ paddedValue = uint8ArrayConcat(
118
+ new Uint8Array(baseTypeSize - value.length),
119
+ value,
120
+ );
121
+ }
122
+ } else {
123
+ paddedValue = value;
124
+ }
125
+ switch (format.bytes) {
126
+ case FMT_BYTES.HEX:
127
+ return bytesToHex(bytesToUint8Array(paddedValue as Bytes));
128
+ case FMT_BYTES.UINT8ARRAY:
129
+ return bytesToUint8Array(paddedValue as Bytes);
130
+ default:
131
+ throw new FormatterError(`Invalid format: ${String(format.bytes)}`);
132
+ }
133
+ }
134
+
135
+ if (baseType === 'string') {
136
+ return String(value);
137
+ }
138
+ } catch (error) {
139
+ // If someone didn't use `eth` keyword we can return original value
140
+ // as the scope of this code is formatting not validation
141
+ return value;
142
+ }
143
+
144
+ return value;
145
+ };
146
+
147
+ const convertArray = ({
148
+ value,
149
+ schemaProp,
150
+ schema,
151
+ object,
152
+ key,
153
+ dataPath,
154
+ format,
155
+ oneOfPath = [],
156
+ }: {
157
+ value: unknown;
158
+ schemaProp: JsonSchema;
159
+ schema: JsonSchema;
160
+ object: Record<string, unknown>;
161
+ key: string;
162
+ dataPath: string[];
163
+ format: DataFormat;
164
+ oneOfPath: [string, number][];
165
+ }) => {
166
+ // If value is an array
167
+ if (Array.isArray(value)) {
168
+ let _schemaProp = schemaProp;
169
+
170
+ // TODO This is a naive approach to solving the issue of
171
+ // a schema using oneOf. This chunk of code was intended to handle
172
+ // BlockSchema.transactions
173
+ // TODO BlockSchema.transactions are not being formatted
174
+ if (schemaProp?.oneOf !== undefined) {
175
+ // The following code is basically saying:
176
+ // if the schema specifies oneOf, then we are to loop
177
+ // over each possible schema and check if they type of the schema
178
+ // matches the type of value[0], and if so we use the oneOfSchemaProp
179
+ // as the schema for formatting
180
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
181
+ schemaProp.oneOf.forEach((oneOfSchemaProp: JsonSchema, index: number) => {
182
+ if (
183
+ !Array.isArray(schemaProp?.items) &&
184
+ ((typeof value[0] === 'object' &&
185
+ (oneOfSchemaProp?.items as JsonSchema)?.type === 'object') ||
186
+ (typeof value[0] === 'string' &&
187
+ (oneOfSchemaProp?.items as JsonSchema)?.type !== 'object'))
188
+ ) {
189
+ _schemaProp = oneOfSchemaProp;
190
+ oneOfPath.push([key, index]);
191
+ }
192
+ });
193
+ }
194
+
195
+ if (isNullish(_schemaProp?.items)) {
196
+ // Can not find schema for array item, delete that item
197
+ // eslint-disable-next-line no-param-reassign
198
+ delete object[key];
199
+ dataPath.pop();
200
+
201
+ return true;
202
+ }
203
+
204
+ // If schema for array items is a single type
205
+ if (isObject(_schemaProp.items) && !isNullish(_schemaProp.items.format)) {
206
+ for (let i = 0; i < value.length; i += 1) {
207
+ // eslint-disable-next-line no-param-reassign
208
+ (object[key] as unknown[])[i] = convertScalarValue(
209
+ value[i],
210
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
211
+ _schemaProp?.items?.format,
212
+ format,
213
+ );
214
+ }
215
+
216
+ dataPath.pop();
217
+ return true;
218
+ }
219
+
220
+ // If schema for array items is an object
221
+ if (!Array.isArray(_schemaProp?.items) && _schemaProp?.items?.type === 'object') {
222
+ for (const arrObject of value) {
223
+ // eslint-disable-next-line no-use-before-define
224
+ convert(
225
+ arrObject as Record<string, unknown> | unknown[],
226
+ schema,
227
+ dataPath,
228
+ format,
229
+ oneOfPath,
230
+ );
231
+ }
232
+
233
+ dataPath.pop();
234
+ return true;
235
+ }
236
+
237
+ // If schema for array is a tuple
238
+ if (Array.isArray(_schemaProp?.items)) {
239
+ for (let i = 0; i < value.length; i += 1) {
240
+ // eslint-disable-next-line no-param-reassign
241
+ (object[key] as unknown[])[i] = convertScalarValue(
242
+ value[i],
243
+ _schemaProp.items[i].format as string,
244
+ format,
245
+ );
246
+ }
247
+
248
+ dataPath.pop();
249
+ return true;
250
+ }
251
+ }
252
+ return false;
253
+ };
254
+
255
+ /**
256
+ * Converts the data to the specified format
257
+ * @param data - data to convert
258
+ * @param schema - The JSON schema that describes the structure of the data
259
+ * @param dataPath - A string array that specifies the path to the data within the JSON schema
260
+ * @param format - The format to be converted to
261
+ * @param oneOfPath - An optional array of two-element tuples that specifies the "oneOf" option to choose, if the schema has oneOf and the data path can match multiple subschemas
262
+ * @returns - The data converted to the specified format
263
+ */
264
+ export const convert = (
265
+ data: Record<string, unknown> | unknown[] | unknown,
266
+ schema: JsonSchema,
267
+ dataPath: string[],
268
+ format: DataFormat,
269
+ oneOfPath: [string, number][] = [],
270
+ ) => {
271
+ // If it's a scalar value
272
+ if (!isObject(data) && !Array.isArray(data)) {
273
+ return convertScalarValue(data, schema?.format as string, format);
274
+ }
275
+
276
+ const object = data as Record<string, unknown>;
277
+ // case when schema is array and `items` is object
278
+ if (
279
+ Array.isArray(object) &&
280
+ schema?.type === 'array' &&
281
+ (schema?.items as JsonSchema)?.type === 'object'
282
+ ) {
283
+ convertArray({
284
+ value: object,
285
+ schemaProp: schema,
286
+ schema,
287
+ object,
288
+ key: '',
289
+ dataPath,
290
+ format,
291
+ oneOfPath,
292
+ });
293
+ } else {
294
+ for (const [key, value] of Object.entries(object)) {
295
+ dataPath.push(key);
296
+ let schemaProp = findSchemaByDataPath(schema, dataPath, oneOfPath);
297
+
298
+ // If value is a scaler value
299
+ if (isNullish(schemaProp)) {
300
+ delete object[key];
301
+ dataPath.pop();
302
+
303
+ continue;
304
+ }
305
+
306
+ // If value is an object, recurse into it
307
+ if (isObject(value)) {
308
+ convert(value, schema, dataPath, format, oneOfPath);
309
+ dataPath.pop();
310
+ continue;
311
+ }
312
+
313
+ // If value is an array
314
+ if (
315
+ convertArray({
316
+ value,
317
+ schemaProp,
318
+ schema,
319
+ object,
320
+ key,
321
+ dataPath,
322
+ format,
323
+ oneOfPath,
324
+ })
325
+ ) {
326
+ continue;
327
+ }
328
+
329
+ // The following code is basically saying:
330
+ // if the schema specifies oneOf, then we are to loop
331
+ // over each possible schema and check if they type of the schema specifies format
332
+ // and if so we use the oneOfSchemaProp as the schema for formatting
333
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
334
+ if (schemaProp?.format === undefined && schemaProp?.oneOf !== undefined) {
335
+ for (const [_index, oneOfSchemaProp] of schemaProp.oneOf.entries()) {
336
+ if (oneOfSchemaProp?.format !== undefined) {
337
+ schemaProp = oneOfSchemaProp;
338
+ break;
339
+ }
340
+ }
341
+ }
342
+
343
+ object[key] = convertScalarValue(value, schemaProp.format as string, format);
344
+
345
+ dataPath.pop();
346
+ }
347
+ }
348
+
349
+ return object;
350
+ };
351
+
352
+ /**
353
+ * Given data that can be interpreted according to the provided schema, returns equivalent data that has been formatted
354
+ * according to the provided return format.
355
+ *
356
+ * @param schema - how to interpret the data
357
+ * @param data - data to be formatted
358
+ * @param returnFormat - how to format the data
359
+ * @returns - formatted data
360
+ *
361
+ * @example
362
+ *
363
+ * ```js
364
+ * import { FMT_NUMBER, utils } from "web3";
365
+ *
366
+ * console.log(
367
+ * utils.format({ format: "uint" }, "221", { number: FMT_NUMBER.HEX }),
368
+ * );
369
+ * // 0xdd
370
+ * ```
371
+ *
372
+ */
373
+ export const format = <
374
+ DataType extends Record<string, unknown> | unknown[] | unknown,
375
+ ReturnType extends DataFormat,
376
+ >(
377
+ schema: ValidationSchemaInput | JsonSchema,
378
+ data: DataType,
379
+ returnFormat: ReturnType = DEFAULT_RETURN_FORMAT as ReturnType,
380
+ ): FormatType<DataType, ReturnType> => {
381
+ let dataToParse: Record<string, unknown> | unknown[] | unknown;
382
+
383
+ if (isObject(data)) {
384
+ dataToParse = mergeDeep({}, data);
385
+ } else if (Array.isArray(data)) {
386
+ dataToParse = [...data];
387
+ } else {
388
+ dataToParse = data;
389
+ }
390
+
391
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
392
+ const jsonSchema: JsonSchema = isObject(schema) ? schema : utils.ethAbiToJsonSchema(schema);
393
+
394
+ if (!jsonSchema.properties && !jsonSchema.items && !jsonSchema.format) {
395
+ throw new FormatterError('Invalid json schema for formatting');
396
+ }
397
+
398
+ return convert(dataToParse, jsonSchema, [], returnFormat) as FormatType<
399
+ typeof data,
400
+ ReturnType
401
+ >;
402
+ };