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,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';
|