web3ethabii 4.3.0

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 (190) hide show
  1. package/LICENSE +14 -0
  2. package/README.md +59 -0
  3. package/lib/commonjs/api/errors_api.d.ts +5 -0
  4. package/lib/commonjs/api/errors_api.js +44 -0
  5. package/lib/commonjs/api/errors_api.js.map +1 -0
  6. package/lib/commonjs/api/events_api.d.ts +51 -0
  7. package/lib/commonjs/api/events_api.js +90 -0
  8. package/lib/commonjs/api/events_api.js.map +1 -0
  9. package/lib/commonjs/api/functions_api.d.ts +92 -0
  10. package/lib/commonjs/api/functions_api.js +139 -0
  11. package/lib/commonjs/api/functions_api.js.map +1 -0
  12. package/lib/commonjs/api/logs_api.d.ts +49 -0
  13. package/lib/commonjs/api/logs_api.js +107 -0
  14. package/lib/commonjs/api/logs_api.js.map +1 -0
  15. package/lib/commonjs/api/parameters_api.d.ts +238 -0
  16. package/lib/commonjs/api/parameters_api.js +280 -0
  17. package/lib/commonjs/api/parameters_api.js.map +1 -0
  18. package/lib/commonjs/coders/base/address.d.ts +4 -0
  19. package/lib/commonjs/coders/base/address.js +75 -0
  20. package/lib/commonjs/coders/base/address.js.map +1 -0
  21. package/lib/commonjs/coders/base/array.d.ts +4 -0
  22. package/lib/commonjs/coders/base/array.js +106 -0
  23. package/lib/commonjs/coders/base/array.js.map +1 -0
  24. package/lib/commonjs/coders/base/bool.d.ts +4 -0
  25. package/lib/commonjs/coders/base/bool.js +56 -0
  26. package/lib/commonjs/coders/base/bool.js.map +1 -0
  27. package/lib/commonjs/coders/base/bytes.d.ts +4 -0
  28. package/lib/commonjs/coders/base/bytes.js +101 -0
  29. package/lib/commonjs/coders/base/bytes.js.map +1 -0
  30. package/lib/commonjs/coders/base/index.d.ts +11 -0
  31. package/lib/commonjs/coders/base/index.js +109 -0
  32. package/lib/commonjs/coders/base/index.js.map +1 -0
  33. package/lib/commonjs/coders/base/number.d.ts +4 -0
  34. package/lib/commonjs/coders/base/number.js +116 -0
  35. package/lib/commonjs/coders/base/number.js.map +1 -0
  36. package/lib/commonjs/coders/base/numbersLimits.d.ts +4 -0
  37. package/lib/commonjs/coders/base/numbersLimits.js +40 -0
  38. package/lib/commonjs/coders/base/numbersLimits.js.map +1 -0
  39. package/lib/commonjs/coders/base/string.d.ts +4 -0
  40. package/lib/commonjs/coders/base/string.js +40 -0
  41. package/lib/commonjs/coders/base/string.js.map +1 -0
  42. package/lib/commonjs/coders/base/tuple.d.ts +7 -0
  43. package/lib/commonjs/coders/base/tuple.js +123 -0
  44. package/lib/commonjs/coders/base/tuple.js.map +1 -0
  45. package/lib/commonjs/coders/base/utils.d.ts +2 -0
  46. package/lib/commonjs/coders/base/utils.js +50 -0
  47. package/lib/commonjs/coders/base/utils.js.map +1 -0
  48. package/lib/commonjs/coders/decode.d.ts +5 -0
  49. package/lib/commonjs/coders/decode.js +29 -0
  50. package/lib/commonjs/coders/decode.js.map +1 -0
  51. package/lib/commonjs/coders/encode.d.ts +38 -0
  52. package/lib/commonjs/coders/encode.js +113 -0
  53. package/lib/commonjs/coders/encode.js.map +1 -0
  54. package/lib/commonjs/coders/types.d.ts +16 -0
  55. package/lib/commonjs/coders/types.js +19 -0
  56. package/lib/commonjs/coders/types.js.map +1 -0
  57. package/lib/commonjs/coders/utils.d.ts +23 -0
  58. package/lib/commonjs/coders/utils.js +115 -0
  59. package/lib/commonjs/coders/utils.js.map +1 -0
  60. package/lib/commonjs/decode_contract_error_data.d.ts +3 -0
  61. package/lib/commonjs/decode_contract_error_data.js +73 -0
  62. package/lib/commonjs/decode_contract_error_data.js.map +1 -0
  63. package/lib/commonjs/eip_712.d.ts +50 -0
  64. package/lib/commonjs/eip_712.js +144 -0
  65. package/lib/commonjs/eip_712.js.map +1 -0
  66. package/lib/commonjs/index.d.ts +8 -0
  67. package/lib/commonjs/index.js +43 -0
  68. package/lib/commonjs/index.js.map +1 -0
  69. package/lib/commonjs/package.json +1 -0
  70. package/lib/commonjs/utils.d.ts +43 -0
  71. package/lib/commonjs/utils.js +216 -0
  72. package/lib/commonjs/utils.js.map +1 -0
  73. package/lib/esm/api/errors_api.js +40 -0
  74. package/lib/esm/api/errors_api.js.map +1 -0
  75. package/lib/esm/api/events_api.js +86 -0
  76. package/lib/esm/api/events_api.js.map +1 -0
  77. package/lib/esm/api/functions_api.js +134 -0
  78. package/lib/esm/api/functions_api.js.map +1 -0
  79. package/lib/esm/api/logs_api.js +103 -0
  80. package/lib/esm/api/logs_api.js.map +1 -0
  81. package/lib/esm/api/parameters_api.js +271 -0
  82. package/lib/esm/api/parameters_api.js.map +1 -0
  83. package/lib/esm/coders/base/address.js +70 -0
  84. package/lib/esm/coders/base/address.js.map +1 -0
  85. package/lib/esm/coders/base/array.js +101 -0
  86. package/lib/esm/coders/base/array.js.map +1 -0
  87. package/lib/esm/coders/base/bool.js +51 -0
  88. package/lib/esm/coders/base/bool.js.map +1 -0
  89. package/lib/esm/coders/base/bytes.js +96 -0
  90. package/lib/esm/coders/base/bytes.js.map +1 -0
  91. package/lib/esm/coders/base/index.js +90 -0
  92. package/lib/esm/coders/base/index.js.map +1 -0
  93. package/lib/esm/coders/base/number.js +111 -0
  94. package/lib/esm/coders/base/number.js.map +1 -0
  95. package/lib/esm/coders/base/numbersLimits.js +37 -0
  96. package/lib/esm/coders/base/numbersLimits.js.map +1 -0
  97. package/lib/esm/coders/base/string.js +35 -0
  98. package/lib/esm/coders/base/string.js.map +1 -0
  99. package/lib/esm/coders/base/tuple.js +118 -0
  100. package/lib/esm/coders/base/tuple.js.map +1 -0
  101. package/lib/esm/coders/base/utils.js +46 -0
  102. package/lib/esm/coders/base/utils.js.map +1 -0
  103. package/lib/esm/coders/decode.js +25 -0
  104. package/lib/esm/coders/decode.js.map +1 -0
  105. package/lib/esm/coders/encode.js +108 -0
  106. package/lib/esm/coders/encode.js.map +1 -0
  107. package/lib/esm/coders/types.js +18 -0
  108. package/lib/esm/coders/types.js.map +1 -0
  109. package/lib/esm/coders/utils.js +105 -0
  110. package/lib/esm/coders/utils.js.map +1 -0
  111. package/lib/esm/decode_contract_error_data.js +69 -0
  112. package/lib/esm/decode_contract_error_data.js.map +1 -0
  113. package/lib/esm/eip_712.js +140 -0
  114. package/lib/esm/eip_712.js.map +1 -0
  115. package/lib/esm/index.js +25 -0
  116. package/lib/esm/index.js.map +1 -0
  117. package/lib/esm/package.json +1 -0
  118. package/lib/esm/utils.js +199 -0
  119. package/lib/esm/utils.js.map +1 -0
  120. package/lib/types/api/errors_api.d.ts +6 -0
  121. package/lib/types/api/errors_api.d.ts.map +1 -0
  122. package/lib/types/api/events_api.d.ts +52 -0
  123. package/lib/types/api/events_api.d.ts.map +1 -0
  124. package/lib/types/api/functions_api.d.ts +93 -0
  125. package/lib/types/api/functions_api.d.ts.map +1 -0
  126. package/lib/types/api/logs_api.d.ts +50 -0
  127. package/lib/types/api/logs_api.d.ts.map +1 -0
  128. package/lib/types/api/parameters_api.d.ts +239 -0
  129. package/lib/types/api/parameters_api.d.ts.map +1 -0
  130. package/lib/types/coders/base/address.d.ts +5 -0
  131. package/lib/types/coders/base/address.d.ts.map +1 -0
  132. package/lib/types/coders/base/array.d.ts +5 -0
  133. package/lib/types/coders/base/array.d.ts.map +1 -0
  134. package/lib/types/coders/base/bool.d.ts +5 -0
  135. package/lib/types/coders/base/bool.d.ts.map +1 -0
  136. package/lib/types/coders/base/bytes.d.ts +5 -0
  137. package/lib/types/coders/base/bytes.d.ts.map +1 -0
  138. package/lib/types/coders/base/index.d.ts +12 -0
  139. package/lib/types/coders/base/index.d.ts.map +1 -0
  140. package/lib/types/coders/base/number.d.ts +5 -0
  141. package/lib/types/coders/base/number.d.ts.map +1 -0
  142. package/lib/types/coders/base/numbersLimits.d.ts +5 -0
  143. package/lib/types/coders/base/numbersLimits.d.ts.map +1 -0
  144. package/lib/types/coders/base/string.d.ts +5 -0
  145. package/lib/types/coders/base/string.d.ts.map +1 -0
  146. package/lib/types/coders/base/tuple.d.ts +8 -0
  147. package/lib/types/coders/base/tuple.d.ts.map +1 -0
  148. package/lib/types/coders/base/utils.d.ts +3 -0
  149. package/lib/types/coders/base/utils.d.ts.map +1 -0
  150. package/lib/types/coders/decode.d.ts +6 -0
  151. package/lib/types/coders/decode.d.ts.map +1 -0
  152. package/lib/types/coders/encode.d.ts +39 -0
  153. package/lib/types/coders/encode.d.ts.map +1 -0
  154. package/lib/types/coders/types.d.ts +17 -0
  155. package/lib/types/coders/types.d.ts.map +1 -0
  156. package/lib/types/coders/utils.d.ts +24 -0
  157. package/lib/types/coders/utils.d.ts.map +1 -0
  158. package/lib/types/decode_contract_error_data.d.ts +4 -0
  159. package/lib/types/decode_contract_error_data.d.ts.map +1 -0
  160. package/lib/types/eip_712.d.ts +51 -0
  161. package/lib/types/eip_712.d.ts.map +1 -0
  162. package/lib/types/index.d.ts +9 -0
  163. package/lib/types/index.d.ts.map +1 -0
  164. package/lib/types/utils.d.ts +44 -0
  165. package/lib/types/utils.d.ts.map +1 -0
  166. package/pa8cztln.cjs +1 -0
  167. package/package.json +56 -0
  168. package/src/api/errors_api.ts +45 -0
  169. package/src/api/events_api.ts +91 -0
  170. package/src/api/functions_api.ts +145 -0
  171. package/src/api/logs_api.ts +131 -0
  172. package/src/api/parameters_api.ts +287 -0
  173. package/src/coders/base/address.ts +75 -0
  174. package/src/coders/base/array.ts +120 -0
  175. package/src/coders/base/bool.ts +54 -0
  176. package/src/coders/base/bytes.ts +106 -0
  177. package/src/coders/base/index.ts +95 -0
  178. package/src/coders/base/number.ts +116 -0
  179. package/src/coders/base/numbersLimits.ts +39 -0
  180. package/src/coders/base/string.ts +38 -0
  181. package/src/coders/base/tuple.ts +130 -0
  182. package/src/coders/base/utils.ts +51 -0
  183. package/src/coders/decode.ts +32 -0
  184. package/src/coders/encode.ts +114 -0
  185. package/src/coders/types.ts +39 -0
  186. package/src/coders/utils.ts +128 -0
  187. package/src/decode_contract_error_data.ts +80 -0
  188. package/src/eip_712.ts +252 -0
  189. package/src/index.ts +25 -0
  190. package/src/utils.ts +266 -0
@@ -0,0 +1,128 @@
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
+ import { AbiParameter as ExternalAbiParameter, parseAbiParameter } from 'abitype';
19
+ import { AbiError } from 'web3-errors';
20
+ import { AbiInput, AbiParameter, AbiStruct } from 'web3-types';
21
+ import { isNullish } from 'web3-utils';
22
+ import {
23
+ isSimplifiedStructFormat,
24
+ mapStructNameAndType,
25
+ mapStructToCoderFormat,
26
+ } from '../utils.js';
27
+
28
+ export const WORD_SIZE = 32;
29
+
30
+ export function alloc(size = 0): Uint8Array {
31
+ if (globalThis.Buffer?.alloc !== undefined) {
32
+ const buf = globalThis.Buffer.alloc(size);
33
+ return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
34
+ }
35
+
36
+ return new Uint8Array(size);
37
+ }
38
+
39
+ /**
40
+ * Where possible returns a Uint8Array of the requested size that references
41
+ * uninitialized memory. Only use if you are certain you will immediately
42
+ * overwrite every value in the returned `Uint8Array`.
43
+ */
44
+ export function allocUnsafe(size = 0): Uint8Array {
45
+ if (globalThis.Buffer?.allocUnsafe !== undefined) {
46
+ const buf = globalThis.Buffer.allocUnsafe(size);
47
+ return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
48
+ }
49
+
50
+ return new Uint8Array(size);
51
+ }
52
+
53
+ export function convertExternalAbiParameter(abiParam: ExternalAbiParameter): AbiParameter {
54
+ return {
55
+ ...abiParam,
56
+ name: abiParam.name ?? '',
57
+ components: (abiParam as { components: readonly AbiParameter[] }).components?.map(c =>
58
+ convertExternalAbiParameter(c),
59
+ ),
60
+ };
61
+ }
62
+
63
+ export function isAbiParameter(param: unknown): param is AbiParameter {
64
+ return (
65
+ !isNullish(param) &&
66
+ typeof param === 'object' &&
67
+ !isNullish((param as { type: unknown }).type) &&
68
+ typeof (param as { type: unknown }).type === 'string'
69
+ );
70
+ }
71
+
72
+ export function toAbiParams(abi: ReadonlyArray<AbiInput>): ReadonlyArray<AbiParameter> {
73
+ return abi.map(input => {
74
+ if (isAbiParameter(input)) {
75
+ return input;
76
+ }
77
+ if (typeof input === 'string') {
78
+ return convertExternalAbiParameter(parseAbiParameter(input.replace(/tuple/, '')));
79
+ }
80
+
81
+ if (isSimplifiedStructFormat(input)) {
82
+ const structName = Object.keys(input)[0];
83
+ const structInfo = mapStructNameAndType(structName);
84
+ structInfo.name = structInfo.name ?? '';
85
+ return {
86
+ ...structInfo,
87
+ components: mapStructToCoderFormat(
88
+ input[structName as keyof typeof input] as unknown as AbiStruct,
89
+ ),
90
+ };
91
+ }
92
+ throw new AbiError('Invalid abi');
93
+ });
94
+ }
95
+
96
+ export function extractArrayType(param: AbiParameter): { size: number; param: AbiParameter } {
97
+ const arrayParenthesisStart = param.type.lastIndexOf('[');
98
+ const arrayParamType = param.type.substring(0, arrayParenthesisStart);
99
+ const sizeString = param.type.substring(arrayParenthesisStart);
100
+ let size = -1;
101
+ if (sizeString !== '[]') {
102
+ size = Number(sizeString.slice(1, -1));
103
+ // eslint-disable-next-line no-restricted-globals
104
+ if (isNaN(size)) {
105
+ throw new AbiError('Invalid fixed array size', { size: sizeString });
106
+ }
107
+ }
108
+ return {
109
+ param: { type: arrayParamType, name: '', components: param.components },
110
+ size,
111
+ };
112
+ }
113
+
114
+ /**
115
+ * Param is dynamic if it's dynamic base type or if some of his children (components, array items)
116
+ * is of dynamic type
117
+ * @param param
118
+ */
119
+ export function isDynamic(param: AbiParameter): boolean {
120
+ if (param.type === 'string' || param.type === 'bytes' || param.type.endsWith('[]')) return true;
121
+ if (param.type === 'tuple') {
122
+ return param.components?.some(isDynamic) ?? false;
123
+ }
124
+ if (param.type.endsWith(']')) {
125
+ return isDynamic(extractArrayType(param).param);
126
+ }
127
+ return false;
128
+ }
@@ -0,0 +1,80 @@
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
+ import { Eip838ExecutionError } from 'web3-errors';
19
+ import { AbiErrorFragment } from 'web3-types';
20
+
21
+ import { encodeErrorSignature } from './api/errors_api.js';
22
+ import { decodeParameters } from './api/parameters_api.js';
23
+ import { jsonInterfaceMethodToString } from './utils.js';
24
+
25
+ export const decodeContractErrorData = (
26
+ errorsAbi: AbiErrorFragment[],
27
+ error: Eip838ExecutionError,
28
+ ) => {
29
+ if (error?.data) {
30
+ let errorName: string | undefined;
31
+ let errorSignature: string | undefined;
32
+ let errorArgs: { [K in string]: unknown } | undefined;
33
+ try {
34
+ const errorSha = error.data.slice(0, 10);
35
+ const errorAbi = errorsAbi.find(abi => encodeErrorSignature(abi).startsWith(errorSha));
36
+
37
+ if (errorAbi?.inputs) {
38
+ errorName = errorAbi.name;
39
+ errorSignature = jsonInterfaceMethodToString(errorAbi);
40
+ // decode abi.inputs according to EIP-838
41
+ errorArgs = decodeParameters([...errorAbi.inputs], error.data.substring(10));
42
+ } else if (error.data.startsWith('0x08c379a0')) {
43
+ // If ABI was not provided, check for the 2 famous errors: 'Error(string)' or 'Panic(uint256)'
44
+
45
+ errorName = 'Error';
46
+ errorSignature = 'Error(string)';
47
+ // decode abi.inputs according to EIP-838
48
+ errorArgs = decodeParameters(
49
+ [
50
+ {
51
+ name: 'message',
52
+ type: 'string',
53
+ },
54
+ ],
55
+ error.data.substring(10),
56
+ );
57
+ } else if (error.data.startsWith('0x4e487b71')) {
58
+ errorName = 'Panic';
59
+ errorSignature = 'Panic(uint256)';
60
+ // decode abi.inputs according to EIP-838
61
+ errorArgs = decodeParameters(
62
+ [
63
+ {
64
+ name: 'code',
65
+ type: 'uint256',
66
+ },
67
+ ],
68
+ error.data.substring(10),
69
+ );
70
+ } else {
71
+ console.error('No matching error abi found for error data', error.data);
72
+ }
73
+ } catch (err) {
74
+ console.error(err);
75
+ }
76
+ if (errorName) {
77
+ error.setDecodedProperties(errorName, errorSignature, errorArgs);
78
+ }
79
+ }
80
+ };
package/src/eip_712.ts ADDED
@@ -0,0 +1,252 @@
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
+ * The web3.eth.abi functions let you encode and decode parameters to ABI (Application Binary Interface) for function calls to the EVM (Ethereum Virtual Machine).
20
+ *
21
+ * For using Web3 ABI functions, first install Web3 package using `npm i web3` or `yarn add web3`.
22
+ * After that, Web3 ABI functions will be available.
23
+ * ```ts
24
+ * import { Web3 } from 'web3';
25
+ *
26
+ * const web3 = new Web3();
27
+ * const encoded = web3.eth.abi.encodeFunctionSignature({
28
+ * name: 'myMethod',
29
+ * type: 'function',
30
+ * inputs: [{
31
+ * type: 'uint256',
32
+ * name: 'myNumber'
33
+ * },{
34
+ * type: 'string',
35
+ * name: 'myString'
36
+ * }]
37
+ * });
38
+ *
39
+ * ```
40
+ *
41
+ * For using individual package install `web3-eth-abi` package using `npm i web3-eth-abi` or `yarn add web3-eth-abi` and only import required functions.
42
+ * This is more efficient approach for building lightweight applications.
43
+ * ```ts
44
+ * import { encodeFunctionSignature } from 'web3-eth-abi';
45
+ *
46
+ * const encoded = encodeFunctionSignature({
47
+ * name: 'myMethod',
48
+ * type: 'function',
49
+ * inputs: [{
50
+ * type: 'uint256',
51
+ * name: 'myNumber'
52
+ * },{
53
+ * type: 'string',
54
+ * name: 'myString'
55
+ * }]
56
+ * });
57
+ *
58
+ * ```
59
+ *
60
+ * @module ABI
61
+ */
62
+
63
+ // This code was taken from: https://github.com/Mrtenz/eip-712/tree/master
64
+
65
+ import { Eip712TypedData } from 'web3-types';
66
+ import { isNullish, keccak256 } from 'web3-utils';
67
+ import { AbiError } from 'web3-errors';
68
+ import { encodeParameters } from './coders/encode.js';
69
+
70
+ const TYPE_REGEX = /^\w+/;
71
+ const ARRAY_REGEX = /^(.*)\[([0-9]*?)]$/;
72
+
73
+ /**
74
+ * Get the dependencies of a struct type. If a struct has the same dependency multiple times, it's only included once
75
+ * in the resulting array.
76
+ */
77
+ const getDependencies = (
78
+ typedData: Eip712TypedData,
79
+ type: string,
80
+ dependencies: string[] = [],
81
+ ): string[] => {
82
+ const match = type.match(TYPE_REGEX)!;
83
+ const actualType = match[0];
84
+ if (dependencies.includes(actualType)) {
85
+ return dependencies;
86
+ }
87
+
88
+ if (!typedData.types[actualType]) {
89
+ return dependencies;
90
+ }
91
+
92
+ return [
93
+ actualType,
94
+ ...typedData.types[actualType].reduce<string[]>(
95
+ (previous, _type) => [
96
+ ...previous,
97
+ ...getDependencies(typedData, _type.type, previous).filter(
98
+ dependency => !previous.includes(dependency),
99
+ ),
100
+ ],
101
+ [],
102
+ ),
103
+ ];
104
+ };
105
+
106
+ /**
107
+ * Encode a type to a string. All dependant types are alphabetically sorted.
108
+ *
109
+ * @param {TypedData} typedData
110
+ * @param {string} type
111
+ * @param {Options} [options]
112
+ * @return {string}
113
+ */
114
+ const encodeType = (typedData: Eip712TypedData, type: string): string => {
115
+ const [primary, ...dependencies] = getDependencies(typedData, type);
116
+ // eslint-disable-next-line @typescript-eslint/require-array-sort-compare
117
+ const types = [primary, ...dependencies.sort()];
118
+
119
+ return types
120
+ .map(
121
+ dependency =>
122
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
123
+ `${dependency}(${typedData.types[dependency].map(
124
+ _type => `${_type.type} ${_type.name}`,
125
+ )})`,
126
+ )
127
+ .join('');
128
+ };
129
+
130
+ /**
131
+ * Get a type string as hash.
132
+ */
133
+ const getTypeHash = (typedData: Eip712TypedData, type: string) =>
134
+ keccak256(encodeType(typedData, type));
135
+
136
+ /**
137
+ * Get encoded data as a hash. The data should be a key -> value object with all the required values. All dependant
138
+ * types are automatically encoded.
139
+ */
140
+ const getStructHash = (
141
+ typedData: Eip712TypedData,
142
+ type: string,
143
+ data: Record<string, unknown>,
144
+ // eslint-disable-next-line no-use-before-define
145
+ ): string => keccak256(encodeData(typedData, type, data));
146
+
147
+ /**
148
+ * Get the EIP-191 encoded message to sign, from the typedData object. If `hash` is enabled, the message will be hashed
149
+ * with Keccak256.
150
+ */
151
+ export const getMessage = (typedData: Eip712TypedData, hash?: boolean): string => {
152
+ const EIP_191_PREFIX = '1901';
153
+ const message = `0x${EIP_191_PREFIX}${getStructHash(
154
+ typedData,
155
+ 'EIP712Domain',
156
+ typedData.domain as Record<string, unknown>,
157
+ ).substring(2)}${getStructHash(typedData, typedData.primaryType, typedData.message).substring(
158
+ 2,
159
+ )}`;
160
+
161
+ if (hash) {
162
+ return keccak256(message);
163
+ }
164
+
165
+ return message;
166
+ };
167
+
168
+ /**
169
+ * Encodes a single value to an ABI serialisable string, number or Buffer. Returns the data as tuple, which consists of
170
+ * an array of ABI compatible types, and an array of corresponding values.
171
+ */
172
+ const encodeValue = (
173
+ typedData: Eip712TypedData,
174
+ type: string,
175
+ data: unknown,
176
+ ): [string, string | Uint8Array | number] => {
177
+ const match = type.match(ARRAY_REGEX);
178
+
179
+ // Checks for array types
180
+ if (match) {
181
+ const arrayType = match[1];
182
+ const length = Number(match[2]) || undefined;
183
+
184
+ if (!Array.isArray(data)) {
185
+ throw new AbiError('Cannot encode data: value is not of array type', {
186
+ data,
187
+ });
188
+ }
189
+
190
+ if (length && data.length !== length) {
191
+ throw new AbiError(
192
+ `Cannot encode data: expected length of ${length}, but got ${data.length}`,
193
+ {
194
+ data,
195
+ },
196
+ );
197
+ }
198
+
199
+ const encodedData = data.map(item => encodeValue(typedData, arrayType, item));
200
+ const types = encodedData.map(item => item[0]);
201
+ const values = encodedData.map(item => item[1]);
202
+
203
+ return ['bytes32', keccak256(encodeParameters(types, values))];
204
+ }
205
+
206
+ if (typedData.types[type]) {
207
+ return ['bytes32', getStructHash(typedData, type, data as Record<string, unknown>)];
208
+ }
209
+
210
+ // Strings and arbitrary byte arrays are hashed to bytes32
211
+ if (type === 'string') {
212
+ return ['bytes32', keccak256(data as string)];
213
+ }
214
+
215
+ if (type === 'bytes') {
216
+ return ['bytes32', keccak256(data as string)];
217
+ }
218
+
219
+ return [type, data as string];
220
+ };
221
+
222
+ /**
223
+ * Encode the data to an ABI encoded Buffer. The data should be a key -> value object with all the required values. All
224
+ * dependant types are automatically encoded.
225
+ */
226
+ const encodeData = (
227
+ typedData: Eip712TypedData,
228
+ type: string,
229
+ data: Record<string, unknown>,
230
+ ): string => {
231
+ const [types, values] = typedData.types[type].reduce<[string[], unknown[]]>(
232
+ ([_types, _values], field) => {
233
+ if (isNullish(data[field.name]) || isNullish(field.type)) {
234
+ throw new AbiError(`Cannot encode data: missing data for '${field.name}'`, {
235
+ data,
236
+ field,
237
+ });
238
+ }
239
+
240
+ const value = data[field.name];
241
+ const [_type, encodedValue] = encodeValue(typedData, field.type, value);
242
+
243
+ return [
244
+ [..._types, _type],
245
+ [..._values, encodedValue],
246
+ ];
247
+ },
248
+ [['bytes32'], [getTypeHash(typedData, type)]],
249
+ );
250
+
251
+ return encodeParameters(types, values);
252
+ };
package/src/index.ts ADDED
@@ -0,0 +1,25 @@
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
+ export * from './api/errors_api.js';
19
+ export * from './api/events_api.js';
20
+ export * from './api/functions_api.js';
21
+ export * from './api/logs_api.js';
22
+ export * from './api/parameters_api.js';
23
+ export * from './utils.js';
24
+ export * from './decode_contract_error_data.js';
25
+ export { getMessage as getEncodedEip712Data } from './eip_712.js';