UNPKG

@nucypher/taco

Version:

### [`nucypher/taco-web`](../../README.md)

78 lines 3.11 kB
import { EthAddressSchema } from '@nucypher/shared'; import { ethers } from 'ethers'; import { z } from 'zod'; import { blockchainParamOrContextParamSchema } from './context'; import { rpcConditionSchema } from './rpc'; // TODO: Consider replacing with `z.unknown`: // Since Solidity types are tied to Solidity version, we may not be able to accurately represent them in Zod. // Alternatively, find a TS Solidity type lib. const EthBaseTypes = [ 'bool', 'string', 'address', 'address payable', ...Array.from({ length: 32 }, (_v, i) => `bytes${i + 1}`), // bytes1 through bytes32 'bytes', ...Array.from({ length: 32 }, (_v, i) => `uint${8 * (i + 1)}`), // uint8 through uint256 ...Array.from({ length: 32 }, (_v, i) => `int${8 * (i + 1)}`), // int8 through int256 ]; export const functionAbiVariableSchema = z .object({ name: z.string(), type: z.enum(EthBaseTypes), internalType: z.enum(EthBaseTypes), // TODO: Do we need to validate this? }) .strict(); export const functionAbiSchema = z .object({ name: z.string(), type: z.literal('function'), inputs: z.array(functionAbiVariableSchema).min(0), outputs: z.array(functionAbiVariableSchema).nonempty(), stateMutability: z.union([z.literal('view'), z.literal('pure')]), }) .strict() .refine((functionAbi) => { let asInterface; try { // `stringify` here because ethers.utils.Interface doesn't accept a Zod schema asInterface = new ethers.utils.Interface(JSON.stringify([functionAbi])); } catch (e) { return false; } const functionsInAbi = Object.values(asInterface.functions || {}); return functionsInAbi.length === 1; }, { message: '"functionAbi" must contain a single function definition', path: ['functionAbi'], }) .refine((functionAbi) => { const asInterface = new ethers.utils.Interface(JSON.stringify([functionAbi])); const nrOfInputs = asInterface.fragments[0].inputs.length; return functionAbi.inputs.length === nrOfInputs; }, { message: '"parameters" must have the same length as "functionAbi.inputs"', path: ['parameters'], }); export const ContractConditionType = 'contract'; export const contractConditionSchema = rpcConditionSchema .extend({ conditionType: z .literal(ContractConditionType) .default(ContractConditionType), contractAddress: EthAddressSchema, standardContractType: z.enum(['ERC20', 'ERC721']).optional(), method: z.string(), functionAbi: functionAbiSchema.optional(), parameters: z.array(blockchainParamOrContextParamSchema), }) // Adding this custom logic causes the return type to be ZodEffects instead of ZodObject // https://github.com/colinhacks/zod/issues/2474 .refine( // A check to see if either 'standardContractType' or 'functionAbi' is set (data) => Boolean(data.standardContractType) !== Boolean(data.functionAbi), { message: "At most one of the fields 'standardContractType' and 'functionAbi' must be defined", path: ['standardContractType'], }); //# sourceMappingURL=contract.js.map