web-eth-abi 4.3.0
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +14 -0
- package/README.md +59 -0
- package/lib/commonjs/api/errors_api.d.ts +5 -0
- package/lib/commonjs/api/errors_api.js +44 -0
- package/lib/commonjs/api/errors_api.js.map +1 -0
- package/lib/commonjs/api/events_api.d.ts +51 -0
- package/lib/commonjs/api/events_api.js +90 -0
- package/lib/commonjs/api/events_api.js.map +1 -0
- package/lib/commonjs/api/functions_api.d.ts +92 -0
- package/lib/commonjs/api/functions_api.js +139 -0
- package/lib/commonjs/api/functions_api.js.map +1 -0
- package/lib/commonjs/api/logs_api.d.ts +49 -0
- package/lib/commonjs/api/logs_api.js +107 -0
- package/lib/commonjs/api/logs_api.js.map +1 -0
- package/lib/commonjs/api/parameters_api.d.ts +238 -0
- package/lib/commonjs/api/parameters_api.js +280 -0
- package/lib/commonjs/api/parameters_api.js.map +1 -0
- package/lib/commonjs/coders/base/address.d.ts +4 -0
- package/lib/commonjs/coders/base/address.js +75 -0
- package/lib/commonjs/coders/base/address.js.map +1 -0
- package/lib/commonjs/coders/base/array.d.ts +4 -0
- package/lib/commonjs/coders/base/array.js +106 -0
- package/lib/commonjs/coders/base/array.js.map +1 -0
- package/lib/commonjs/coders/base/bool.d.ts +4 -0
- package/lib/commonjs/coders/base/bool.js +56 -0
- package/lib/commonjs/coders/base/bool.js.map +1 -0
- package/lib/commonjs/coders/base/bytes.d.ts +4 -0
- package/lib/commonjs/coders/base/bytes.js +101 -0
- package/lib/commonjs/coders/base/bytes.js.map +1 -0
- package/lib/commonjs/coders/base/index.d.ts +11 -0
- package/lib/commonjs/coders/base/index.js +109 -0
- package/lib/commonjs/coders/base/index.js.map +1 -0
- package/lib/commonjs/coders/base/number.d.ts +4 -0
- package/lib/commonjs/coders/base/number.js +116 -0
- package/lib/commonjs/coders/base/number.js.map +1 -0
- package/lib/commonjs/coders/base/numbersLimits.d.ts +4 -0
- package/lib/commonjs/coders/base/numbersLimits.js +40 -0
- package/lib/commonjs/coders/base/numbersLimits.js.map +1 -0
- package/lib/commonjs/coders/base/string.d.ts +4 -0
- package/lib/commonjs/coders/base/string.js +40 -0
- package/lib/commonjs/coders/base/string.js.map +1 -0
- package/lib/commonjs/coders/base/tuple.d.ts +7 -0
- package/lib/commonjs/coders/base/tuple.js +123 -0
- package/lib/commonjs/coders/base/tuple.js.map +1 -0
- package/lib/commonjs/coders/base/utils.d.ts +2 -0
- package/lib/commonjs/coders/base/utils.js +50 -0
- package/lib/commonjs/coders/base/utils.js.map +1 -0
- package/lib/commonjs/coders/decode.d.ts +5 -0
- package/lib/commonjs/coders/decode.js +29 -0
- package/lib/commonjs/coders/decode.js.map +1 -0
- package/lib/commonjs/coders/encode.d.ts +38 -0
- package/lib/commonjs/coders/encode.js +113 -0
- package/lib/commonjs/coders/encode.js.map +1 -0
- package/lib/commonjs/coders/types.d.ts +16 -0
- package/lib/commonjs/coders/types.js +19 -0
- package/lib/commonjs/coders/types.js.map +1 -0
- package/lib/commonjs/coders/utils.d.ts +23 -0
- package/lib/commonjs/coders/utils.js +115 -0
- package/lib/commonjs/coders/utils.js.map +1 -0
- package/lib/commonjs/decode_contract_error_data.d.ts +3 -0
- package/lib/commonjs/decode_contract_error_data.js +73 -0
- package/lib/commonjs/decode_contract_error_data.js.map +1 -0
- package/lib/commonjs/eip_712.d.ts +50 -0
- package/lib/commonjs/eip_712.js +144 -0
- package/lib/commonjs/eip_712.js.map +1 -0
- package/lib/commonjs/index.d.ts +8 -0
- package/lib/commonjs/index.js +43 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/utils.d.ts +43 -0
- package/lib/commonjs/utils.js +216 -0
- package/lib/commonjs/utils.js.map +1 -0
- package/lib/esm/api/errors_api.js +40 -0
- package/lib/esm/api/errors_api.js.map +1 -0
- package/lib/esm/api/events_api.js +86 -0
- package/lib/esm/api/events_api.js.map +1 -0
- package/lib/esm/api/functions_api.js +134 -0
- package/lib/esm/api/functions_api.js.map +1 -0
- package/lib/esm/api/logs_api.js +103 -0
- package/lib/esm/api/logs_api.js.map +1 -0
- package/lib/esm/api/parameters_api.js +271 -0
- package/lib/esm/api/parameters_api.js.map +1 -0
- package/lib/esm/coders/base/address.js +70 -0
- package/lib/esm/coders/base/address.js.map +1 -0
- package/lib/esm/coders/base/array.js +101 -0
- package/lib/esm/coders/base/array.js.map +1 -0
- package/lib/esm/coders/base/bool.js +51 -0
- package/lib/esm/coders/base/bool.js.map +1 -0
- package/lib/esm/coders/base/bytes.js +96 -0
- package/lib/esm/coders/base/bytes.js.map +1 -0
- package/lib/esm/coders/base/index.js +90 -0
- package/lib/esm/coders/base/index.js.map +1 -0
- package/lib/esm/coders/base/number.js +111 -0
- package/lib/esm/coders/base/number.js.map +1 -0
- package/lib/esm/coders/base/numbersLimits.js +37 -0
- package/lib/esm/coders/base/numbersLimits.js.map +1 -0
- package/lib/esm/coders/base/string.js +35 -0
- package/lib/esm/coders/base/string.js.map +1 -0
- package/lib/esm/coders/base/tuple.js +118 -0
- package/lib/esm/coders/base/tuple.js.map +1 -0
- package/lib/esm/coders/base/utils.js +46 -0
- package/lib/esm/coders/base/utils.js.map +1 -0
- package/lib/esm/coders/decode.js +25 -0
- package/lib/esm/coders/decode.js.map +1 -0
- package/lib/esm/coders/encode.js +108 -0
- package/lib/esm/coders/encode.js.map +1 -0
- package/lib/esm/coders/types.js +18 -0
- package/lib/esm/coders/types.js.map +1 -0
- package/lib/esm/coders/utils.js +105 -0
- package/lib/esm/coders/utils.js.map +1 -0
- package/lib/esm/decode_contract_error_data.js +69 -0
- package/lib/esm/decode_contract_error_data.js.map +1 -0
- package/lib/esm/eip_712.js +140 -0
- package/lib/esm/eip_712.js.map +1 -0
- package/lib/esm/index.js +25 -0
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/package.json +1 -0
- package/lib/esm/utils.js +199 -0
- package/lib/esm/utils.js.map +1 -0
- package/lib/types/api/errors_api.d.ts +6 -0
- package/lib/types/api/errors_api.d.ts.map +1 -0
- package/lib/types/api/events_api.d.ts +52 -0
- package/lib/types/api/events_api.d.ts.map +1 -0
- package/lib/types/api/functions_api.d.ts +93 -0
- package/lib/types/api/functions_api.d.ts.map +1 -0
- package/lib/types/api/logs_api.d.ts +50 -0
- package/lib/types/api/logs_api.d.ts.map +1 -0
- package/lib/types/api/parameters_api.d.ts +239 -0
- package/lib/types/api/parameters_api.d.ts.map +1 -0
- package/lib/types/coders/base/address.d.ts +5 -0
- package/lib/types/coders/base/address.d.ts.map +1 -0
- package/lib/types/coders/base/array.d.ts +5 -0
- package/lib/types/coders/base/array.d.ts.map +1 -0
- package/lib/types/coders/base/bool.d.ts +5 -0
- package/lib/types/coders/base/bool.d.ts.map +1 -0
- package/lib/types/coders/base/bytes.d.ts +5 -0
- package/lib/types/coders/base/bytes.d.ts.map +1 -0
- package/lib/types/coders/base/index.d.ts +12 -0
- package/lib/types/coders/base/index.d.ts.map +1 -0
- package/lib/types/coders/base/number.d.ts +5 -0
- package/lib/types/coders/base/number.d.ts.map +1 -0
- package/lib/types/coders/base/numbersLimits.d.ts +5 -0
- package/lib/types/coders/base/numbersLimits.d.ts.map +1 -0
- package/lib/types/coders/base/string.d.ts +5 -0
- package/lib/types/coders/base/string.d.ts.map +1 -0
- package/lib/types/coders/base/tuple.d.ts +8 -0
- package/lib/types/coders/base/tuple.d.ts.map +1 -0
- package/lib/types/coders/base/utils.d.ts +3 -0
- package/lib/types/coders/base/utils.d.ts.map +1 -0
- package/lib/types/coders/decode.d.ts +6 -0
- package/lib/types/coders/decode.d.ts.map +1 -0
- package/lib/types/coders/encode.d.ts +39 -0
- package/lib/types/coders/encode.d.ts.map +1 -0
- package/lib/types/coders/types.d.ts +17 -0
- package/lib/types/coders/types.d.ts.map +1 -0
- package/lib/types/coders/utils.d.ts +24 -0
- package/lib/types/coders/utils.d.ts.map +1 -0
- package/lib/types/decode_contract_error_data.d.ts +4 -0
- package/lib/types/decode_contract_error_data.d.ts.map +1 -0
- package/lib/types/eip_712.d.ts +51 -0
- package/lib/types/eip_712.d.ts.map +1 -0
- package/lib/types/index.d.ts +9 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/utils.d.ts +44 -0
- package/lib/types/utils.d.ts.map +1 -0
- package/package.json +56 -0
- package/src/api/errors_api.ts +45 -0
- package/src/api/events_api.ts +91 -0
- package/src/api/functions_api.ts +145 -0
- package/src/api/logs_api.ts +131 -0
- package/src/api/parameters_api.ts +287 -0
- package/src/coders/base/address.ts +75 -0
- package/src/coders/base/array.ts +120 -0
- package/src/coders/base/bool.ts +54 -0
- package/src/coders/base/bytes.ts +106 -0
- package/src/coders/base/index.ts +95 -0
- package/src/coders/base/number.ts +116 -0
- package/src/coders/base/numbersLimits.ts +39 -0
- package/src/coders/base/string.ts +38 -0
- package/src/coders/base/tuple.ts +130 -0
- package/src/coders/base/utils.ts +51 -0
- package/src/coders/decode.ts +32 -0
- package/src/coders/encode.ts +114 -0
- package/src/coders/types.ts +39 -0
- package/src/coders/utils.ts +128 -0
- package/src/decode_contract_error_data.ts +80 -0
- package/src/eip_712.ts +252 -0
- package/src/index.ts +25 -0
- package/src/utils.ts +266 -0
- 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
|
+
};
|