Skip to content

Commit

Permalink
fix: strict tuple rule, type bugfix, basic tuple validator
Browse files Browse the repository at this point in the history
  • Loading branch information
tabaktoni committed Feb 8, 2023
1 parent acfab34 commit 1c97279
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/utils/calldata/cairo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const isLen = (name: string) => /_len$/.test(name);
export const isTypeFelt = (type: string) => type === 'felt';
export const isTypeFeltArray = (type: string) => type === 'felt*';
export const isTypeArray = (type: string) => /\*/.test(type);
export const isTypeTuple = (type: string) => /\(.*\)/i.test(type);
export const isTypeTuple = (type: string) => /^\(.*\)$/i.test(type);
export const isTypeNamedTuple = (type: string) => /\(.*\)/i.test(type) && type.includes(':');
export const isTypeStruct = (type: string, structs: abiStructs) => type in structs;

Expand Down
2 changes: 1 addition & 1 deletion src/utils/calldata/requestParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function parseTuple(element: object, typeStr: string): Tupled[] {
return memberTypes.map((it: any, dx: number) => {
return {
element: elements[dx],
type: it.type,
type: it.type ?? it,
};
});
}
Expand Down
34 changes: 18 additions & 16 deletions src/utils/calldata/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const validateStruct = (parameter: any, input: AbiEntry, structs: abiStructs) =>
`Validate: arg ${input.name} is cairo type struct (${input.type}), and should be defined as js object (not array)`
);

// shallow struct validation, only first depth level
structs[input.type].members.forEach(({ name }) => {
assert(
Object.keys(parameter).includes(name),
Expand All @@ -47,22 +48,23 @@ const validateArray = (parameter: any, input: AbiEntry, structs: abiStructs) =>
if (isTypeFelt(baseType) && isLongText(parameter)) return;

assert(Array.isArray(parameter), `Validate: arg ${input.name} should be an Array`);
// Array of Felts
if (isTypeFelt(baseType)) {
parameter.forEach((param: BigNumberish) => validateFelt(param, input));
// Array of Tuple
} else if (/\(felt/.test(input.type)) {
// todo: this is not true it can be like (Struct.. or (Tuple...)
// TODO: This ex. code validate only most basic tuple structure, skip for validation
// Array of Struct
} else if (isTypeStruct(baseType, structs)) {
parameter.forEach((structParam: any) =>
validateStruct(structParam, { name: input.name, type: baseType }, structs)
);
} else {
throw new Error(
`Validate Unhandled: argument ${input.name}, type ${input.type}, value ${parameter}`
);

switch (true) {
case isTypeFelt(baseType):
parameter.forEach((param: BigNumberish) => validateFelt(param, input));
break;
case isTypeTuple(baseType):
parameter.forEach((it: any) => validateTuple(it, { name: input.name, type: baseType }));
break;
case isTypeStruct(baseType, structs):
parameter.forEach((it: any) =>
validateStruct(it, { name: input.name, type: baseType }, structs)
);
break;
default:
throw new Error(
`Validate Unhandled: argument ${input.name}, type ${input.type}, value ${parameter}`
);
}
};

Expand Down

0 comments on commit 1c97279

Please sign in to comment.