From 486ba8ac2b75359507d07a1651f84574e280ed04 Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 3 Jan 2024 14:03:35 +0300 Subject: [PATCH] tried some modifier tricks, this is good enough as is --- src/contracts/modifiers/apply.ts | 48 +++++++++++++++++++++++++++++++ src/contracts/modifiers/index.ts | 49 ++------------------------------ 2 files changed, 50 insertions(+), 47 deletions(-) create mode 100644 src/contracts/modifiers/apply.ts diff --git a/src/contracts/modifiers/apply.ts b/src/contracts/modifiers/apply.ts new file mode 100644 index 0000000..6ec2666 --- /dev/null +++ b/src/contracts/modifiers/apply.ts @@ -0,0 +1,48 @@ +import type {ContractInputGeneric, ContractState} from '../types'; + +/** + * Apply allows one to execute modifiers which are functions that are run + * before the function body is executed, similar to [Solidity modifiers](https://docs.soliditylang.org/en/latest/contracts.html#function-modifiers). + * + * The first three arguments are mandatory, and the remaining arguments are expected to be modifier functions. These modifiers + * will run in the order they appear, and if all pass, a result with the same type of the input is returned. + * + * For example, consider a function call with the following type: + * + * ```ts + * { + * function: "divide", + * value: { + * a: number, + * b: number, + * } + * } + * ``` + * + * We take two numbers and return `a/b`. We can write a modifier to ensure `b` is non-zero. + * + * ```ts + * const {a, b} = await apply(caller, input.value, state, + * (caller, input, state) => { + * if (input.b === 0) { + * throw new Error("denominator cant be zero"); + * } + * return input; + * } + * ); + * ``` + * + * Due to the generic template parameters, when `apply` is used within the switch-case of the `handle` function, it gets type-safety + * based on which function is being handled! + */ +export async function apply( + caller: string, + input: I, + state: S, + ...modifiers: ((caller: string, input: I, state: S) => I | Promise)[] +): Promise { + for (const modifier of modifiers) { + input = await modifier(caller, input, state); + } + return input; +} diff --git a/src/contracts/modifiers/index.ts b/src/contracts/modifiers/index.ts index 9faf33f..a170752 100644 --- a/src/contracts/modifiers/index.ts +++ b/src/contracts/modifiers/index.ts @@ -1,3 +1,5 @@ +export {apply} from './apply'; + import {ExpectedProofError, InvalidProofError, NotOwnerError, NotWhitelistedError, NullValueError} from '../errors'; import {verifyProof} from '../utils'; import {ContractState} from '../types'; @@ -77,50 +79,3 @@ export const onlyProofVerified = { - * if (input.b === 0) { - * throw new Error("denominator cant be zero"); - * } - * return input; - * } - * ); - * ``` - * - * Due to the generic template parameters, when `apply` is used within the switch-case of the `handle` function, it gets type-safety - * based on which function is being handled! - */ -export async function apply( - caller: string, - input: I, - state: S, - ...modifiers: ((caller: string, input: I, state: S) => I | Promise)[] -): Promise { - for (const modifier of modifiers) { - input = await modifier(caller, input, state); - } - return input; -}