Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.

Commit 4f423fc

Browse files
authoredMay 30, 2023
Fix validation of nested tuples (#6125)
* fix nested * fix tests * skip in3 * fix * fix validator import
1 parent 408332d commit 4f423fc

File tree

3 files changed

+114
-10
lines changed

3 files changed

+114
-10
lines changed
 

‎packages/web3-validator/src/utils.ts

+14-6
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export const abiSchemaToJsonSchema = (
138138
let abiName!: string;
139139
let abiComponents: ShortValidationSchema | FullValidationSchema | undefined = [];
140140

141-
// If its a complete Abi Parameter
141+
// If it's a complete Abi Parameter
142142
// e.g. {name: 'a', type: 'uint'}
143143
if (isAbiParameterSchema(abi)) {
144144
abiType = abi.type;
@@ -149,11 +149,19 @@ export const abiSchemaToJsonSchema = (
149149
abiType = abi;
150150
abiName = `${level}/${index}`;
151151

152-
// If its provided in short form of tuple e.g. [['uint', 'string']]
152+
// If it's provided in short form of tuple e.g. [['uint', 'string']]
153153
} else if (Array.isArray(abi)) {
154154
// If its custom tuple e.g. ['tuple[2]', ['uint', 'string']]
155-
if (abi[1] && Array.isArray(abi[1])) {
156-
abiType = abi[0] as string;
155+
if (
156+
abi[0] &&
157+
typeof abi[0] === 'string' &&
158+
abi[0].startsWith('tuple') &&
159+
!Array.isArray(abi[0]) &&
160+
abi[1] &&
161+
Array.isArray(abi[1])
162+
) {
163+
// eslint-disable-next-line prefer-destructuring
164+
abiType = abi[0];
157165
abiName = `${level}/${index}`;
158166
abiComponents = abi[1] as ReadonlyArray<ShortValidationSchema>;
159167
} else {
@@ -258,7 +266,7 @@ export const transformJsonDataToAbiFormat = (
258266
let abiName!: string;
259267
let abiComponents: ShortValidationSchema | FullValidationSchema | undefined = [];
260268

261-
// If its a complete Abi Parameter
269+
// If it's a complete Abi Parameter
262270
// e.g. {name: 'a', type: 'uint'}
263271
if (isAbiParameterSchema(abi)) {
264272
abiType = abi.type;
@@ -268,7 +276,7 @@ export const transformJsonDataToAbiFormat = (
268276
} else if (typeof abi === 'string') {
269277
abiType = abi;
270278

271-
// If its provided in short form of tuple e.g. [['uint', 'string']]
279+
// If it's provided in short form of tuple e.g. [['uint', 'string']]
272280
} else if (Array.isArray(abi)) {
273281
// If its custom tuple e.g. ['tuple[2]', ['uint', 'string']]
274282
if (abi[1] && Array.isArray(abi[1])) {

‎packages/web3-validator/src/validator.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,11 @@ import { Web3ValidationErrorObject } from 'web3-types';
1818

1919
import { toHex, utf8ToBytes } from 'ethereum-cryptography/utils';
2020
import { blake2b } from 'ethereum-cryptography/blake2b';
21+
import validator from 'is-my-json-valid';
2122
import formats from './formats';
2223
import { Web3ValidatorError } from './errors';
2324
import { Validate, Json, Schema, RawValidationError } from './types';
2425

25-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
26-
const validator = require('is-my-json-valid');
27-
2826
export class Validator {
2927
// eslint-disable-next-line no-use-before-define
3028
private static validatorInstance?: Validator;
@@ -48,6 +46,7 @@ export class Validator {
4846
// eslint-disable-next-line class-methods-use-this
4947
private createValidator(schema: Schema): Validate {
5048
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
49+
// @ts-expect-error validator params correction
5150
return validator(schema, {
5251
formats,
5352
greedy: true,
@@ -91,8 +90,10 @@ export class Validator {
9190

9291
const { field } = error;
9392
const _instancePath =
93+
schemaPath ||
9494
// eslint-disable-next-line no-useless-escape
95-
field?.length >= 4 ? `${field.slice(4).replace(/\"|\[|\]/g, '')}` : '/';
95+
(field?.length >= 4 ? `${field.slice(4).replace(/\"|\[|\]/g, '')}` : '/');
96+
9697
const instancePath = _instancePath ? `/${_instancePath}` : '';
9798
if (error?.message === 'has less items than allowed') {
9899
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
Original file line numberDiff line numberDiff line change
@@ -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+
import { Web3Validator } from '../../src/web3_validator';
18+
19+
describe('web3-validator', () => {
20+
describe('Web3Validator', () => {
21+
let validator: Web3Validator;
22+
23+
beforeEach(() => {
24+
validator = new Web3Validator();
25+
});
26+
describe('validate', () => {
27+
it('nested tuples', () => {
28+
const schema = [['uint', 'uint'], 'uint'];
29+
validator.validate(schema, [[7, 5], 3]);
30+
});
31+
it('nested tuples deep', () => {
32+
const address = '0x7ab80aeb6bb488b7f6c41c58e83ef248eb39c882';
33+
34+
const schema = [
35+
[
36+
['uint', ['uint', ['uint', ['uint', 'uint'], 'address']]],
37+
['uint', 'uint'],
38+
],
39+
'uint',
40+
];
41+
validator.validate(schema, [
42+
[
43+
[7, [7, [7, [7, 5], address]]],
44+
[7, 5],
45+
],
46+
3,
47+
]);
48+
});
49+
it('nested tuples deep object schema', () => {
50+
const schema = {
51+
type: 'array',
52+
items: [
53+
{
54+
$id: '/0/0',
55+
format: 'uint',
56+
required: true,
57+
},
58+
{
59+
type: 'array',
60+
items: [
61+
{
62+
$id: '/0/0',
63+
format: 'uint',
64+
required: true,
65+
},
66+
{
67+
type: 'array',
68+
items: [
69+
{
70+
$id: '/0/0',
71+
format: 'uint',
72+
required: true,
73+
},
74+
{
75+
$id: '/0/1',
76+
format: 'uint',
77+
required: true,
78+
},
79+
],
80+
maxItems: 2,
81+
minItems: 2,
82+
},
83+
],
84+
maxItems: 2,
85+
minItems: 2,
86+
},
87+
],
88+
maxItems: 2,
89+
minItems: 2,
90+
};
91+
expect(validator.validateJSONSchema(schema, [7, [7, [7, 5]]])).toBeUndefined();
92+
});
93+
});
94+
});
95+
});

0 commit comments

Comments
 (0)
This repository has been archived.