web-eth-abi 4.3.0

Sign up to get free protection for your applications and to get access to all the features.
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/package.json +56 -0
  167. package/src/api/errors_api.ts +45 -0
  168. package/src/api/events_api.ts +91 -0
  169. package/src/api/functions_api.ts +145 -0
  170. package/src/api/logs_api.ts +131 -0
  171. package/src/api/parameters_api.ts +287 -0
  172. package/src/coders/base/address.ts +75 -0
  173. package/src/coders/base/array.ts +120 -0
  174. package/src/coders/base/bool.ts +54 -0
  175. package/src/coders/base/bytes.ts +106 -0
  176. package/src/coders/base/index.ts +95 -0
  177. package/src/coders/base/number.ts +116 -0
  178. package/src/coders/base/numbersLimits.ts +39 -0
  179. package/src/coders/base/string.ts +38 -0
  180. package/src/coders/base/tuple.ts +130 -0
  181. package/src/coders/base/utils.ts +51 -0
  182. package/src/coders/decode.ts +32 -0
  183. package/src/coders/encode.ts +114 -0
  184. package/src/coders/types.ts +39 -0
  185. package/src/coders/utils.ts +128 -0
  186. package/src/decode_contract_error_data.ts +80 -0
  187. package/src/eip_712.ts +252 -0
  188. package/src/index.ts +25 -0
  189. package/src/utils.ts +266 -0
  190. package/wimho03d.cjs +1 -0
@@ -0,0 +1,95 @@
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 } from 'web3-types';
19
+ import { AbiError } from 'web3-errors';
20
+ import { EncoderResult, DecoderResult } from '../types.js';
21
+ import { decodeAddress, encodeAddress } from './address.js';
22
+ import { decodeBool, encodeBoolean } from './bool.js';
23
+ import { decodeBytes, encodeBytes } from './bytes.js';
24
+ import { decodeNumber, encodeNumber } from './number.js';
25
+ import { decodeString, encodeString } from './string.js';
26
+ // eslint-disable-next-line import/no-cycle
27
+ import { decodeTuple, encodeTuple } from './tuple.js';
28
+ // eslint-disable-next-line import/no-cycle
29
+ import { decodeArray, encodeArray } from './array.js';
30
+
31
+ export { encodeAddress, decodeAddress } from './address.js';
32
+ export { encodeBoolean, decodeBool } from './bool.js';
33
+ export { encodeBytes, decodeBytes } from './bytes.js';
34
+ export { encodeNumber, decodeNumber } from './number.js';
35
+ export { encodeString, decodeString } from './string.js';
36
+ // eslint-disable-next-line import/no-cycle
37
+ export { encodeTuple, decodeTuple } from './tuple.js';
38
+ // eslint-disable-next-line import/no-cycle
39
+ export { encodeArray, decodeArray } from './array.js';
40
+
41
+ export function encodeParamFromAbiParameter(param: AbiParameter, value: unknown): EncoderResult {
42
+ if (param.type === 'string') {
43
+ return encodeString(param, value);
44
+ }
45
+ if (param.type === 'bool') {
46
+ return encodeBoolean(param, value);
47
+ }
48
+ if (param.type === 'address') {
49
+ return encodeAddress(param, value);
50
+ }
51
+ if (param.type === 'tuple') {
52
+ return encodeTuple(param, value);
53
+ }
54
+ if (param.type.endsWith(']')) {
55
+ return encodeArray(param, value);
56
+ }
57
+ if (param.type.startsWith('bytes')) {
58
+ return encodeBytes(param, value);
59
+ }
60
+ if (param.type.startsWith('uint') || param.type.startsWith('int')) {
61
+ return encodeNumber(param, value);
62
+ }
63
+ throw new AbiError('Unsupported', {
64
+ param,
65
+ value,
66
+ });
67
+ }
68
+
69
+ export function decodeParamFromAbiParameter(param: AbiParameter, bytes: Uint8Array): DecoderResult {
70
+ if (param.type === 'string') {
71
+ return decodeString(param, bytes);
72
+ }
73
+ if (param.type === 'bool') {
74
+ return decodeBool(param, bytes);
75
+ }
76
+ if (param.type === 'address') {
77
+ return decodeAddress(param, bytes);
78
+ }
79
+ if (param.type === 'tuple') {
80
+ return decodeTuple(param, bytes);
81
+ }
82
+ if (param.type.endsWith(']')) {
83
+ return decodeArray(param, bytes);
84
+ }
85
+ if (param.type.startsWith('bytes')) {
86
+ return decodeBytes(param, bytes);
87
+ }
88
+ if (param.type.startsWith('uint') || param.type.startsWith('int')) {
89
+ return decodeNumber(param, bytes);
90
+ }
91
+ throw new AbiError('Unsupported', {
92
+ param,
93
+ bytes,
94
+ });
95
+ }
@@ -0,0 +1,116 @@
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 { AbiError } from 'web3-errors';
19
+ import type { AbiParameter } from 'web3-types';
20
+ import { padLeft, toBigInt } from 'web3-utils';
21
+ import { utils } from 'web3-validator';
22
+ import { DecoderResult, EncoderResult } from '../types.js';
23
+ import { WORD_SIZE } from '../utils.js';
24
+ import { numberLimits } from './numbersLimits.js';
25
+
26
+ // eslint-disable-next-line no-bitwise
27
+ const mask = BigInt(1) << BigInt(256);
28
+
29
+ function bigIntToUint8Array(value: bigint, byteLength = WORD_SIZE): Uint8Array {
30
+ let hexValue;
31
+ if (value < 0) {
32
+ hexValue = (mask + value).toString(16);
33
+ } else {
34
+ hexValue = value.toString(16);
35
+ }
36
+ hexValue = padLeft(hexValue, byteLength * 2);
37
+ return utils.hexToUint8Array(hexValue);
38
+ }
39
+
40
+ function uint8ArrayToBigInt(value: Uint8Array, max: bigint): bigint {
41
+ const hexValue = utils.uint8ArrayToHexString(value);
42
+ const result = BigInt(hexValue);
43
+ if (result <= max) return result;
44
+ return result - mask;
45
+ }
46
+
47
+ export function encodeNumber(param: AbiParameter, input: unknown): EncoderResult {
48
+ let value;
49
+ try {
50
+ value = toBigInt(input);
51
+ } catch (e) {
52
+ throw new AbiError('provided input is not number value', {
53
+ type: param.type,
54
+ value: input,
55
+ name: param.name,
56
+ });
57
+ }
58
+ const limit = numberLimits.get(param.type);
59
+ if (!limit) {
60
+ throw new AbiError('provided abi contains invalid number datatype', { type: param.type });
61
+ }
62
+ if (value < limit.min) {
63
+ throw new AbiError('provided input is less then minimum for given type', {
64
+ type: param.type,
65
+ value: input,
66
+ name: param.name,
67
+ minimum: limit.min.toString(),
68
+ });
69
+ }
70
+ if (value > limit.max) {
71
+ throw new AbiError('provided input is greater then maximum for given type', {
72
+ type: param.type,
73
+ value: input,
74
+ name: param.name,
75
+ maximum: limit.max.toString(),
76
+ });
77
+ }
78
+ return {
79
+ dynamic: false,
80
+ encoded: bigIntToUint8Array(value),
81
+ };
82
+ }
83
+
84
+ export function decodeNumber(param: AbiParameter, bytes: Uint8Array): DecoderResult<bigint> {
85
+ if (bytes.length < WORD_SIZE) {
86
+ throw new AbiError('Not enough bytes left to decode', { param, bytesLeft: bytes.length });
87
+ }
88
+ const boolBytes = bytes.subarray(0, WORD_SIZE);
89
+ const limit = numberLimits.get(param.type);
90
+ if (!limit) {
91
+ throw new AbiError('provided abi contains invalid number datatype', { type: param.type });
92
+ }
93
+ const numberResult = uint8ArrayToBigInt(boolBytes, limit.max);
94
+
95
+ if (numberResult < limit.min) {
96
+ throw new AbiError('decoded value is less then minimum for given type', {
97
+ type: param.type,
98
+ value: numberResult,
99
+ name: param.name,
100
+ minimum: limit.min.toString(),
101
+ });
102
+ }
103
+ if (numberResult > limit.max) {
104
+ throw new AbiError('decoded value is greater then maximum for given type', {
105
+ type: param.type,
106
+ value: numberResult,
107
+ name: param.name,
108
+ maximum: limit.max.toString(),
109
+ });
110
+ }
111
+ return {
112
+ result: numberResult,
113
+ encoded: bytes.subarray(WORD_SIZE),
114
+ consumed: WORD_SIZE,
115
+ };
116
+ }
@@ -0,0 +1,39 @@
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
+ * this variable contains the precalculated limits for all the numbers for uint and int types
20
+ */
21
+ export const numberLimits = new Map<string, { min: bigint; max: bigint }>();
22
+
23
+ let base = BigInt(256); // 2 ^ 8 = 256
24
+ for (let i = 8; i <= 256; i += 8) {
25
+ numberLimits.set(`uint${i}`, {
26
+ min: BigInt(0),
27
+ max: base - BigInt(1),
28
+ });
29
+ numberLimits.set(`int${i}`, {
30
+ min: -base / BigInt(2),
31
+ max: base / BigInt(2) - BigInt(1),
32
+ });
33
+ base *= BigInt(256);
34
+ }
35
+
36
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
37
+ numberLimits.set(`int`, numberLimits.get('int256')!);
38
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
39
+ numberLimits.set(`uint`, numberLimits.get('uint256')!);
@@ -0,0 +1,38 @@
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 { AbiError } from 'web3-errors';
18
+ import { AbiParameter } from 'web3-types';
19
+ import { hexToUtf8, utf8ToBytes } from 'web3-utils';
20
+ import { DecoderResult, EncoderResult } from '../types.js';
21
+ import { decodeBytes, encodeBytes } from './bytes.js';
22
+
23
+ export function encodeString(_param: AbiParameter, input: unknown): EncoderResult {
24
+ if (typeof input !== 'string') {
25
+ throw new AbiError('invalid input, should be string', { input });
26
+ }
27
+ const bytes = utf8ToBytes(input);
28
+ return encodeBytes({ type: 'bytes', name: '' }, bytes);
29
+ }
30
+
31
+ export function decodeString(_param: AbiParameter, bytes: Uint8Array): DecoderResult<string> {
32
+ const r = decodeBytes({ type: 'bytes', name: '' }, bytes);
33
+ return {
34
+ result: hexToUtf8(r.result),
35
+ encoded: r.encoded,
36
+ consumed: r.consumed,
37
+ };
38
+ }
@@ -0,0 +1,130 @@
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 { AbiError } from 'web3-errors';
18
+ import { AbiParameter } from 'web3-types';
19
+ import { uint8ArrayConcat } from 'web3-utils';
20
+ import { DecoderResult, EncoderResult } from '../types.js';
21
+ // eslint-disable-next-line import/no-cycle
22
+ import { decodeParamFromAbiParameter, encodeParamFromAbiParameter } from './index.js';
23
+ import { encodeDynamicParams } from './utils.js';
24
+ import { isDynamic } from '../utils.js';
25
+ import { decodeNumber } from './number.js';
26
+
27
+ export function encodeTuple(param: AbiParameter, input: unknown): EncoderResult {
28
+ let dynamic = false;
29
+ if (!Array.isArray(input) && typeof input !== 'object') {
30
+ throw new AbiError('param must be either Array or Object', {
31
+ param,
32
+ input,
33
+ });
34
+ }
35
+ const narrowedInput = input as Array<unknown> | Record<string, unknown>;
36
+ const encoded: Array<EncoderResult> = [];
37
+ for (let i = 0; i < (param.components?.length ?? 0); i += 1) {
38
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
39
+ const paramComponent = param.components![i];
40
+ let result: EncoderResult;
41
+ if (Array.isArray(narrowedInput)) {
42
+ if (i >= narrowedInput.length) {
43
+ throw new AbiError('input param length missmatch', {
44
+ param,
45
+ input,
46
+ });
47
+ }
48
+ result = encodeParamFromAbiParameter(paramComponent, narrowedInput[i]);
49
+ } else {
50
+ const paramInput = narrowedInput[paramComponent.name ?? ''];
51
+ // eslint-disable-next-line no-null/no-null
52
+ if (paramInput === undefined || paramInput === null) {
53
+ throw new AbiError('missing input defined in abi', {
54
+ param,
55
+ input,
56
+ paramName: paramComponent.name,
57
+ });
58
+ }
59
+ result = encodeParamFromAbiParameter(paramComponent, paramInput);
60
+ }
61
+ if (result.dynamic) {
62
+ dynamic = true;
63
+ }
64
+ encoded.push(result);
65
+ }
66
+
67
+ if (dynamic) {
68
+ return {
69
+ dynamic: true,
70
+ encoded: encodeDynamicParams(encoded),
71
+ };
72
+ }
73
+ return {
74
+ dynamic: false,
75
+ encoded: uint8ArrayConcat(...encoded.map(e => e.encoded)),
76
+ };
77
+ }
78
+
79
+ export function decodeTuple(
80
+ param: AbiParameter,
81
+ bytes: Uint8Array,
82
+ ): DecoderResult<{ [key: string]: unknown; __length__: number }> {
83
+ const result: { [key: string]: unknown; __length__: number } = {
84
+ __length__: 0,
85
+ };
86
+
87
+ // tracks how much static params consumed bytes
88
+ let consumed = 0;
89
+
90
+ if (!param.components) {
91
+ return {
92
+ result,
93
+ encoded: bytes,
94
+ consumed,
95
+ };
96
+ }
97
+ // track how much dynamic params consumed bytes
98
+ let dynamicConsumed = 0;
99
+ for (const [index, childParam] of param.components.entries()) {
100
+ let decodedResult: DecoderResult;
101
+ if (isDynamic(childParam)) {
102
+ // if dynamic, we will have offset encoded
103
+ const offsetResult = decodeNumber(
104
+ { type: 'uint32', name: '' },
105
+ bytes.subarray(consumed),
106
+ );
107
+ // offset counts from start of original byte sequence
108
+ decodedResult = decodeParamFromAbiParameter(
109
+ childParam,
110
+ bytes.subarray(Number(offsetResult.result)),
111
+ );
112
+ consumed += offsetResult.consumed;
113
+ dynamicConsumed += decodedResult.consumed;
114
+ } else {
115
+ // static param, just decode
116
+ decodedResult = decodeParamFromAbiParameter(childParam, bytes.subarray(consumed));
117
+ consumed += decodedResult.consumed;
118
+ }
119
+ result.__length__ += 1;
120
+ result[index] = decodedResult.result;
121
+ if (childParam.name && childParam.name !== '') {
122
+ result[childParam.name] = decodedResult.result;
123
+ }
124
+ }
125
+ return {
126
+ encoded: bytes.subarray(consumed + dynamicConsumed),
127
+ result,
128
+ consumed: consumed + dynamicConsumed,
129
+ };
130
+ }
@@ -0,0 +1,51 @@
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 { uint8ArrayConcat } from 'web3-utils';
18
+ import { EncoderResult } from '../types.js';
19
+ import { WORD_SIZE } from '../utils.js';
20
+ import { encodeNumber } from './number.js';
21
+
22
+ export function encodeDynamicParams(encodedParams: ReadonlyArray<EncoderResult>): Uint8Array {
23
+ let staticSize = 0;
24
+ let dynamicSize = 0;
25
+ const staticParams: EncoderResult[] = [];
26
+ const dynamicParams: EncoderResult[] = [];
27
+ // figure out static size
28
+ for (const encodedParam of encodedParams) {
29
+ if (encodedParam.dynamic) {
30
+ staticSize += WORD_SIZE;
31
+ } else {
32
+ staticSize += encodedParam.encoded.length;
33
+ }
34
+ }
35
+
36
+ for (const encodedParam of encodedParams) {
37
+ if (encodedParam.dynamic) {
38
+ staticParams.push(
39
+ encodeNumber({ type: 'uint256', name: '' }, staticSize + dynamicSize),
40
+ );
41
+ dynamicParams.push(encodedParam);
42
+ dynamicSize += encodedParam.encoded.length;
43
+ } else {
44
+ staticParams.push(encodedParam);
45
+ }
46
+ }
47
+ return uint8ArrayConcat(
48
+ ...staticParams.map(p => p.encoded),
49
+ ...dynamicParams.map(p => p.encoded),
50
+ );
51
+ }
@@ -0,0 +1,32 @@
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 { AbiInput, HexString } from 'web3-types';
19
+ import { utils } from 'web3-validator';
20
+ import { decodeTuple } from './base/tuple.js';
21
+ import { toAbiParams } from './utils.js';
22
+
23
+ export function decodeParameters(
24
+ abis: AbiInput[] | ReadonlyArray<AbiInput>,
25
+ bytes: HexString,
26
+ _loose: boolean,
27
+ ): { [key: string]: unknown; __length__: number } {
28
+ const abiParams = toAbiParams(abis);
29
+ const bytesArray = utils.hexToUint8Array(bytes);
30
+
31
+ return decodeTuple({ type: 'tuple', name: '', components: abiParams }, bytesArray).result;
32
+ }
@@ -0,0 +1,114 @@
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 { AbiError } from 'web3-errors';
18
+ import { AbiInput, AbiParameter } from 'web3-types';
19
+ import { toHex } from 'web3-utils';
20
+ import { utils } from 'web3-validator';
21
+ import { encodeTuple } from './base/index.js';
22
+ import { toAbiParams } from './utils.js';
23
+
24
+ /**
25
+ * @param params - The params to infer the ABI from
26
+ * @returns The inferred ABI
27
+ * @example
28
+ * ```
29
+ * inferParamsAbi([1, -1, 'hello', '0x1234', ])
30
+ * ```
31
+ * > [{ type: 'int256' }, { type: 'uint256' }, { type: 'string' }, { type: 'bytes' }]
32
+ * ```
33
+ */
34
+ function inferParamsAbi(params: unknown[]): ReadonlyArray<AbiParameter> {
35
+ const abi: AbiParameter[] = [];
36
+ params.forEach(param => {
37
+ if (Array.isArray(param)) {
38
+ const inferredParams = inferParamsAbi(param);
39
+ abi.push({
40
+ type: 'tuple',
41
+ components: inferredParams,
42
+ name: '',
43
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
44
+ } as AbiParameter);
45
+ } else {
46
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
47
+ abi.push({ type: toHex(param as any, true) } as AbiParameter);
48
+ }
49
+ });
50
+ return abi;
51
+ }
52
+
53
+ /**
54
+ * Encodes a parameter based on its type to its ABI representation.
55
+ * @param abi - An array of {@link AbiInput}. See [Solidity's documentation](https://solidity.readthedocs.io/en/v0.5.3/abi-spec.html#json) for more details.
56
+ * @param params - The actual parameters to encode.
57
+ * @returns - The ABI encoded parameters
58
+ * @example
59
+ * ```ts
60
+ * const res = web3.eth.abi.encodeParameters(
61
+ * ["uint256", "string"],
62
+ * ["2345675643", "Hello!%"]
63
+ * );
64
+ *
65
+ * console.log(res);
66
+ * > 0x000000000000000000000000000000000000000000000000000000008bd02b7b0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000748656c6c6f212500000000000000000000000000000000000000000000000000
67
+ * ```
68
+ */
69
+ export function encodeParameters(abi: ReadonlyArray<AbiInput>, params: unknown[]): string {
70
+ if (abi?.length !== params.length) {
71
+ throw new AbiError('Invalid number of values received for given ABI', {
72
+ expected: abi?.length,
73
+ received: params.length,
74
+ });
75
+ }
76
+
77
+ const abiParams = toAbiParams(abi);
78
+ return utils.uint8ArrayToHexString(
79
+ encodeTuple({ type: 'tuple', name: '', components: abiParams }, params).encoded,
80
+ );
81
+ }
82
+
83
+ /**
84
+ * Infer a smart contract method parameter type and then encode this parameter.
85
+ * @param params - The parameters to encode.
86
+ * @returns - The ABI encoded parameters
87
+ *
88
+ * @remarks
89
+ * This method is useful when you don't know the type of the parameters you want to encode. It will infer the type of the parameters and then encode them.
90
+ * However, it is not recommended to use this method when you know the type of the parameters you want to encode. In this case, use the {@link encodeParameters} method instead.
91
+ * The type inference is not perfect and can lead to unexpected results. Especially when you want to encode an array, uint that is not uint256 or bytes....
92
+ * @example
93
+ * ```ts
94
+ * const res = web3.eth.abi.encodeParameters(
95
+ * ["2345675643", "Hello!%"]
96
+ * );
97
+ *
98
+ * console.log(res);
99
+ * > 0x000000000000000000000000000000000000000000000000000000008bd02b7b0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000748656c6c6f212500000000000000000000000000000000000000000000000000
100
+ * ```
101
+ */
102
+ export function inferTypesAndEncodeParameters(params: unknown[]): string {
103
+ try {
104
+ const abiParams = inferParamsAbi(params);
105
+ return utils.uint8ArrayToHexString(
106
+ encodeTuple({ type: 'tuple', name: '', components: abiParams }, params).encoded,
107
+ );
108
+ } catch (e) {
109
+ // throws If the inferred params type caused an error
110
+ throw new AbiError('Could not infer types from given params', {
111
+ params,
112
+ });
113
+ }
114
+ }
@@ -0,0 +1,39 @@
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 type EncoderResult = {
19
+ dynamic: boolean;
20
+
21
+ encoded: Uint8Array;
22
+ };
23
+ export type DecoderResult<T = unknown> = {
24
+ result: T;
25
+
26
+ // remaining bytes not yet decoded
27
+ encoded: Uint8Array;
28
+
29
+ // number of bytes consumed
30
+ consumed: number;
31
+ };
32
+
33
+ export type NumberType = {
34
+ signed: boolean;
35
+ byteLength: number;
36
+ };
37
+ export type BytesType = {
38
+ size?: number;
39
+ };