diff --git a/packages/taco/src/conditions/base/contract.ts b/packages/taco/src/conditions/base/contract.ts index 79456ec3..b2295d0a 100644 --- a/packages/taco/src/conditions/base/contract.ts +++ b/packages/taco/src/conditions/base/contract.ts @@ -29,6 +29,23 @@ const functionAbiVariableSchema = z }) .strict(); +export const humanReadableAbiSchema = z + .string() + .refine( + (abi) => { + try { + toJsonAbiFormat(abi); + return true; + } catch (e) { + return false; + } + }, + { + message: 'Invalid Human-Readable ABI format', + }, + ) + .transform(toJsonAbiFormat); + const functionAbiSchema = z .object({ name: z.string(), @@ -78,10 +95,9 @@ function toJsonAbiFormat(humanReadableAbi: string): any { const fragment = ethers.utils.FunctionFragment.from( abiWithoutFunctionKeyword, ); - const jsonAbi = JSON.parse(fragment.format(ethers.utils.FormatTypes.json)); - - delete jsonAbi.constant; - delete jsonAbi.payable; + const { constant, payable, ...jsonAbi } = JSON.parse( + fragment.format(ethers.utils.FormatTypes.json), + ); jsonAbi.inputs = jsonAbi.inputs.map((input: any) => ({ ...input, @@ -108,25 +124,7 @@ export const contractConditionSchema = rpcConditionSchema standardContractType: z.enum(['ERC20', 'ERC721']).optional(), method: z.string(), functionAbi: z - .union([ - functionAbiSchema, - z - .string() - .refine( - (abi) => { - try { - toJsonAbiFormat(abi); - return true; - } catch (e) { - return false; - } - }, - { - message: 'Invalid Human-Readable ABI format', - }, - ) - .transform(toJsonAbiFormat), - ]) + .union([functionAbiSchema, humanReadableAbiSchema]) .optional(), parameters: z.array(paramOrContextParamSchema), }) @@ -143,12 +141,8 @@ export const contractConditionSchema = rpcConditionSchema ); export type ContractConditionProps = z.infer; -interface ContractConditionHumanReadableAbi extends ContractConditionProps { - functionAbi: string; -} - export class ContractCondition extends Condition { - constructor(value: OmitConditionType) { + constructor(value: OmitConditionType) { if (typeof value.functionAbi === 'string') { value.functionAbi = toJsonAbiFormat(value.functionAbi); } diff --git a/packages/taco/test/conditions/base/contract.test.ts b/packages/taco/test/conditions/base/contract.test.ts index e77bd1fc..c8bbf647 100644 --- a/packages/taco/test/conditions/base/contract.test.ts +++ b/packages/taco/test/conditions/base/contract.test.ts @@ -8,6 +8,7 @@ import { contractConditionSchema, ContractConditionType, FunctionAbiProps, + humanReadableAbiSchema, } from '../../../src/conditions/base/contract'; import { ConditionExpression } from '../../../src/conditions/condition-expr'; import { USER_ADDRESS_PARAM } from '../../../src/conditions/const'; @@ -344,7 +345,14 @@ describe('supports custom function abi', () => { functionAbi: humanReadableAbi, method: 'balanceOf', }); + const invalidHumanReadableAbi = 'function invalidAbi'; + expect(() => + humanReadableAbiSchema.parse(humanReadableAbi), + ).not.toThrow(); + expect(() => humanReadableAbiSchema.parse(invalidHumanReadableAbi)).toThrow( + 'Invalid Human-Readable ABI format', + ); expect(condition.value.functionAbi).toEqual({ name: 'balanceOf', type: 'function',