@boostxyz/sdk 0.0.0-alpha.11 → 0.0.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Actions/Action.cjs +1 -1
- package/dist/Actions/Action.js +1 -1
- package/dist/Actions/ContractAction.d.ts +2 -2
- package/dist/Actions/ContractAction.d.ts.map +1 -1
- package/dist/Actions/ERC721MintAction.d.ts +2 -2
- package/dist/Actions/ERC721MintAction.d.ts.map +1 -1
- package/dist/Actions/EventAction.cjs +1 -1
- package/dist/Actions/EventAction.cjs.map +1 -1
- package/dist/Actions/EventAction.d.ts +117 -33
- package/dist/Actions/EventAction.d.ts.map +1 -1
- package/dist/Actions/EventAction.js +309 -121
- package/dist/Actions/EventAction.js.map +1 -1
- package/dist/AllowLists/AllowList.cjs +1 -1
- package/dist/AllowLists/AllowList.js +2 -2
- package/dist/AllowLists/SimpleAllowList.cjs +1 -1
- package/dist/AllowLists/SimpleAllowList.cjs.map +1 -1
- package/dist/AllowLists/SimpleAllowList.d.ts +2 -2
- package/dist/AllowLists/SimpleAllowList.d.ts.map +1 -1
- package/dist/AllowLists/SimpleAllowList.js +23 -19
- package/dist/AllowLists/SimpleAllowList.js.map +1 -1
- package/dist/AllowLists/SimpleDenyList.cjs +1 -1
- package/dist/AllowLists/SimpleDenyList.d.ts +2 -2
- package/dist/AllowLists/SimpleDenyList.d.ts.map +1 -1
- package/dist/AllowLists/SimpleDenyList.js +6 -5
- package/dist/AllowLists/SimpleDenyList.js.map +1 -1
- package/dist/Auth/PassthroughAuth.cjs +1 -1
- package/dist/Auth/PassthroughAuth.js +1 -1
- package/dist/BoostCore.cjs +2 -2
- package/dist/BoostCore.cjs.map +1 -1
- package/dist/BoostCore.d.ts +27 -5
- package/dist/BoostCore.d.ts.map +1 -1
- package/dist/BoostCore.js +438 -347
- package/dist/BoostCore.js.map +1 -1
- package/dist/BoostRegistry.cjs +1 -1
- package/dist/BoostRegistry.cjs.map +1 -1
- package/dist/BoostRegistry.d.ts +26 -5
- package/dist/BoostRegistry.d.ts.map +1 -1
- package/dist/BoostRegistry.js +125 -64
- package/dist/BoostRegistry.js.map +1 -1
- package/dist/Budgets/Budget.cjs +1 -1
- package/dist/Budgets/Budget.js +1 -1
- package/dist/Budgets/ManagedBudget.cjs +1 -1
- package/dist/Budgets/ManagedBudget.cjs.map +1 -1
- package/dist/Budgets/ManagedBudget.d.ts +2 -2
- package/dist/Budgets/ManagedBudget.d.ts.map +1 -1
- package/dist/Budgets/ManagedBudget.js +41 -37
- package/dist/Budgets/ManagedBudget.js.map +1 -1
- package/dist/Budgets/SimpleBudget.d.ts +2 -2
- package/dist/Budgets/SimpleBudget.d.ts.map +1 -1
- package/dist/Budgets/VestingBudget.d.ts +2 -2
- package/dist/Budgets/VestingBudget.d.ts.map +1 -1
- package/dist/Deployable/DeployableTarget.cjs +1 -1
- package/dist/Deployable/DeployableTarget.cjs.map +1 -1
- package/dist/Deployable/DeployableTarget.d.ts +6 -6
- package/dist/Deployable/DeployableTarget.d.ts.map +1 -1
- package/dist/Deployable/DeployableTarget.js +22 -17
- package/dist/Deployable/DeployableTarget.js.map +1 -1
- package/dist/Incentives/AllowListIncentive.cjs +1 -1
- package/dist/Incentives/AllowListIncentive.cjs.map +1 -1
- package/dist/Incentives/AllowListIncentive.d.ts +2 -2
- package/dist/Incentives/AllowListIncentive.d.ts.map +1 -1
- package/dist/Incentives/AllowListIncentive.js +17 -13
- package/dist/Incentives/AllowListIncentive.js.map +1 -1
- package/dist/Incentives/CGDAIncentive.cjs +1 -1
- package/dist/Incentives/CGDAIncentive.cjs.map +1 -1
- package/dist/Incentives/CGDAIncentive.d.ts +14 -2
- package/dist/Incentives/CGDAIncentive.d.ts.map +1 -1
- package/dist/Incentives/CGDAIncentive.js +27 -23
- package/dist/Incentives/CGDAIncentive.js.map +1 -1
- package/dist/Incentives/ERC1155Incentive.d.ts +2 -2
- package/dist/Incentives/ERC1155Incentive.d.ts.map +1 -1
- package/dist/Incentives/ERC20Incentive.cjs +1 -1
- package/dist/Incentives/ERC20Incentive.cjs.map +1 -1
- package/dist/Incentives/ERC20Incentive.d.ts +2 -2
- package/dist/Incentives/ERC20Incentive.d.ts.map +1 -1
- package/dist/Incentives/ERC20Incentive.js +17 -13
- package/dist/Incentives/ERC20Incentive.js.map +1 -1
- package/dist/Incentives/ERC20VariableIncentive.d.ts +2 -2
- package/dist/Incentives/ERC20VariableIncentive.d.ts.map +1 -1
- package/dist/Incentives/Incentive.cjs +1 -1
- package/dist/Incentives/Incentive.cjs.map +1 -1
- package/dist/Incentives/Incentive.js +34 -30
- package/dist/Incentives/Incentive.js.map +1 -1
- package/dist/Incentives/PointsIncentive.cjs +1 -1
- package/dist/Incentives/PointsIncentive.cjs.map +1 -1
- package/dist/Incentives/PointsIncentive.d.ts +2 -2
- package/dist/Incentives/PointsIncentive.d.ts.map +1 -1
- package/dist/Incentives/PointsIncentive.js +13 -9
- package/dist/Incentives/PointsIncentive.js.map +1 -1
- package/dist/{SimpleDenyList-4PtOPXTc.js → SimpleDenyList-C21O9Yfi.js} +23 -19
- package/dist/SimpleDenyList-C21O9Yfi.js.map +1 -0
- package/dist/SimpleDenyList-DeJRKD2D.cjs +2 -0
- package/dist/{SimpleDenyList-4PtOPXTc.js.map → SimpleDenyList-DeJRKD2D.cjs.map} +1 -1
- package/dist/Validators/SignerValidator.cjs +1 -1
- package/dist/Validators/SignerValidator.cjs.map +1 -1
- package/dist/Validators/SignerValidator.d.ts +2 -2
- package/dist/Validators/SignerValidator.d.ts.map +1 -1
- package/dist/Validators/SignerValidator.js +18 -14
- package/dist/Validators/SignerValidator.js.map +1 -1
- package/dist/Validators/Validator.cjs +1 -1
- package/dist/Validators/Validator.js +1 -1
- package/dist/deployments-BvFcK_eR.js +40 -0
- package/dist/deployments-BvFcK_eR.js.map +1 -0
- package/dist/deployments-Ho4PnGCS.cjs +2 -0
- package/dist/deployments-Ho4PnGCS.cjs.map +1 -0
- package/dist/deployments.json +38 -0
- package/dist/errors.cjs +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +122 -20
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +98 -28
- package/dist/errors.js.map +1 -1
- package/dist/{generated-BDeDiaCK.js → generated-LpgSHrH0.js} +150 -110
- package/dist/generated-LpgSHrH0.js.map +1 -0
- package/dist/generated-tq_HLZJ0.cjs +3 -0
- package/dist/generated-tq_HLZJ0.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +115 -108
- package/dist/utils.cjs +1 -1
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.ts +25 -11
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +38 -23
- package/dist/utils.js.map +1 -1
- package/package.json +10 -6
- package/src/Actions/Action.test.ts +8 -4
- package/src/Actions/ContractAction.ts +5 -3
- package/src/Actions/ERC721MintAction.ts +5 -3
- package/src/Actions/EventAction.test.ts +528 -100
- package/src/Actions/EventAction.ts +302 -60
- package/src/AllowLists/AllowList.test.ts +1 -1
- package/src/AllowLists/SimpleAllowList.ts +6 -3
- package/src/AllowLists/SimpleDenyList.ts +6 -3
- package/src/BoostCore.test.ts +31 -91
- package/src/BoostCore.ts +137 -34
- package/src/BoostRegistry.ts +89 -21
- package/src/Budgets/ManagedBudget.ts +6 -4
- package/src/Budgets/SimpleBudget.ts +4 -3
- package/src/Budgets/VestingBudget.ts +4 -3
- package/src/Deployable/DeployableTarget.ts +22 -11
- package/src/Incentives/AllowListIncentive.ts +6 -3
- package/src/Incentives/CGDAIncentive.ts +6 -3
- package/src/Incentives/ERC1155Incentive.ts +4 -3
- package/src/Incentives/ERC20Incentive.ts +6 -3
- package/src/Incentives/ERC20VariableIncentive.ts +6 -3
- package/src/Incentives/PointsIncentive.ts +6 -3
- package/src/Validators/SignerValidator.ts +6 -3
- package/src/errors.ts +177 -21
- package/src/utils.ts +60 -11
- package/dist/SimpleDenyList-CqT0BMP7.cjs +0 -2
- package/dist/SimpleDenyList-CqT0BMP7.cjs.map +0 -1
- package/dist/generated-BDeDiaCK.js.map +0 -1
- package/dist/generated-wKBNvm48.cjs +0 -3
- package/dist/generated-wKBNvm48.cjs.map +0 -1
|
@@ -7,28 +7,41 @@ import {
|
|
|
7
7
|
} from '@boostxyz/evm';
|
|
8
8
|
import { bytecode } from '@boostxyz/evm/artifacts/contracts/actions/EventAction.sol/EventAction.json';
|
|
9
9
|
import events from '@boostxyz/signatures/events';
|
|
10
|
+
import functions from '@boostxyz/signatures/functions';
|
|
10
11
|
import {
|
|
11
12
|
type Abi,
|
|
12
13
|
type AbiEvent,
|
|
14
|
+
type AbiFunction,
|
|
13
15
|
type Address,
|
|
14
16
|
type ContractEventName,
|
|
17
|
+
type ContractFunctionName,
|
|
18
|
+
type GetLogsReturnType,
|
|
19
|
+
type GetTransactionParameters,
|
|
15
20
|
type Hex,
|
|
16
21
|
type Log,
|
|
22
|
+
type PublicClient,
|
|
23
|
+
decodeFunctionData,
|
|
17
24
|
encodeAbiParameters,
|
|
25
|
+
fromHex,
|
|
18
26
|
isAddressEqual,
|
|
27
|
+
trim,
|
|
19
28
|
} from 'viem';
|
|
20
29
|
import { getLogs } from 'viem/actions';
|
|
30
|
+
import { EventAction as EventActionBases } from '../../dist/deployments.json';
|
|
21
31
|
import type {
|
|
22
32
|
DeployableOptions,
|
|
23
33
|
GenericDeployableParams,
|
|
24
34
|
} from '../Deployable/Deployable';
|
|
25
35
|
import { DeployableTarget } from '../Deployable/DeployableTarget';
|
|
26
36
|
import {
|
|
37
|
+
DecodedArgsMalformedError,
|
|
27
38
|
FieldValueNotComparableError,
|
|
28
39
|
FieldValueUndefinedError,
|
|
40
|
+
FunctionDataDecodeError,
|
|
29
41
|
InvalidNumericalCriteriaError,
|
|
30
42
|
NoEventActionStepsProvidedError,
|
|
31
43
|
TooManyEventActionStepsProvidedError,
|
|
44
|
+
UnparseableAbiParamError,
|
|
32
45
|
UnrecognizedFilterTypeError,
|
|
33
46
|
} from '../errors';
|
|
34
47
|
import {
|
|
@@ -55,6 +68,7 @@ export enum FilterType {
|
|
|
55
68
|
GREATER_THAN = 2,
|
|
56
69
|
LESS_THAN = 3,
|
|
57
70
|
CONTAINS = 4,
|
|
71
|
+
REGEX = 5,
|
|
58
72
|
}
|
|
59
73
|
|
|
60
74
|
/**
|
|
@@ -198,6 +212,41 @@ export interface ActionStep {
|
|
|
198
212
|
*/
|
|
199
213
|
actionParameter: Criteria;
|
|
200
214
|
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Parameters for validating an event step.
|
|
218
|
+
*
|
|
219
|
+
* This type omits the 'address' field from GetLogsParams and adds optional fields
|
|
220
|
+
* for logs and known events.
|
|
221
|
+
*
|
|
222
|
+
* @typedef {Object} ValidateEventStepParams
|
|
223
|
+
* @property {Log[]} [logs]
|
|
224
|
+
* @property {Record<Hex, AbiEvent>} [knownEvents]
|
|
225
|
+
* @property {number} [fromBlock]
|
|
226
|
+
* @property {number} [toBlock]
|
|
227
|
+
* @property {Hex} [blockHash]
|
|
228
|
+
* @property {Abi} abi
|
|
229
|
+
* @property {ContractEventName<Abi>} eventName
|
|
230
|
+
*/
|
|
231
|
+
export type ValidateEventStepParams = Omit<
|
|
232
|
+
GetLogsParams<Abi, ContractEventName<Abi>> & {
|
|
233
|
+
logs?: Log[];
|
|
234
|
+
knownEvents?: Record<Hex, AbiEvent>;
|
|
235
|
+
},
|
|
236
|
+
'address'
|
|
237
|
+
>;
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Parameters for validating a function step.
|
|
241
|
+
*
|
|
242
|
+
* This type includes all parameters required to get a transaction.
|
|
243
|
+
*
|
|
244
|
+
* @typedef {Object} ValidateFunctionStepParams
|
|
245
|
+
* @property {Hex} hash
|
|
246
|
+
* @property {number} [chainId]
|
|
247
|
+
*/
|
|
248
|
+
export type ValidateFunctionStepParams = GetTransactionParameters;
|
|
249
|
+
|
|
201
250
|
/**
|
|
202
251
|
* You can either supply a simplified version of the payload, or one that explicitly declares action steps.
|
|
203
252
|
*
|
|
@@ -280,6 +329,26 @@ export interface EventActionPayloadRaw {
|
|
|
280
329
|
actionStepFour: ActionStep;
|
|
281
330
|
}
|
|
282
331
|
|
|
332
|
+
/**
|
|
333
|
+
* Array of event logs to pass into TxParams
|
|
334
|
+
* @export
|
|
335
|
+
* @typedef {EventLogs}
|
|
336
|
+
*/
|
|
337
|
+
export type EventLogs = GetLogsReturnType<AbiEvent, AbiEvent[], true>;
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Getter params from the event action contract
|
|
341
|
+
*
|
|
342
|
+
* @export
|
|
343
|
+
* @typedef {ReadEventActionParams}
|
|
344
|
+
* @param {fnName} fnName - The getter function name
|
|
345
|
+
*/
|
|
346
|
+
export type ReadEventActionParams<
|
|
347
|
+
fnName extends ContractFunctionName<typeof eventActionAbi, 'pure' | 'view'>,
|
|
348
|
+
> = ReadParams<typeof eventActionAbi, fnName>;
|
|
349
|
+
|
|
350
|
+
type TxParams = ValidateEventStepParams | ValidateFunctionStepParams;
|
|
351
|
+
|
|
283
352
|
/**
|
|
284
353
|
* A generic event action
|
|
285
354
|
*
|
|
@@ -305,9 +374,12 @@ export class EventAction extends DeployableTarget<
|
|
|
305
374
|
*
|
|
306
375
|
* @public
|
|
307
376
|
* @static
|
|
308
|
-
* @type {Address}
|
|
377
|
+
* @type {Record<number, Address>}
|
|
309
378
|
*/
|
|
310
|
-
public static override
|
|
379
|
+
public static override bases: Record<number, Address> = {
|
|
380
|
+
...(EventActionBases as Record<number, Address>),
|
|
381
|
+
31337: import.meta.env.VITE_EVENT_ACTION_BASE,
|
|
382
|
+
};
|
|
311
383
|
/**
|
|
312
384
|
* @inheritdoc
|
|
313
385
|
*
|
|
@@ -323,12 +395,12 @@ export class EventAction extends DeployableTarget<
|
|
|
323
395
|
* @public
|
|
324
396
|
* @async
|
|
325
397
|
* @param {number} index The index of the action event to retrieve
|
|
326
|
-
* @param {?
|
|
398
|
+
* @param {?ReadEventActionParams<'getActionStep'>} [params]
|
|
327
399
|
* @returns {Promise<ActionStep>}
|
|
328
400
|
*/
|
|
329
401
|
public async getActionStep(
|
|
330
402
|
index: number,
|
|
331
|
-
params?:
|
|
403
|
+
params?: ReadEventActionParams<'getActionStep'>,
|
|
332
404
|
) {
|
|
333
405
|
const steps = await this.getActionSteps(params);
|
|
334
406
|
return steps.at(index);
|
|
@@ -339,11 +411,11 @@ export class EventAction extends DeployableTarget<
|
|
|
339
411
|
*
|
|
340
412
|
* @public
|
|
341
413
|
* @async
|
|
342
|
-
* @param {?
|
|
414
|
+
* @param {?ReadEventActionParams<'getActionSteps'>} [params]
|
|
343
415
|
* @returns {Promise<ActionStep[]>}
|
|
344
416
|
*/
|
|
345
417
|
public async getActionSteps(
|
|
346
|
-
params?:
|
|
418
|
+
params?: ReadEventActionParams<'getActionSteps'>,
|
|
347
419
|
) {
|
|
348
420
|
const steps = (await readEventActionGetActionSteps(this._config, {
|
|
349
421
|
address: this.assertValidAddress(),
|
|
@@ -359,11 +431,11 @@ export class EventAction extends DeployableTarget<
|
|
|
359
431
|
*
|
|
360
432
|
* @public
|
|
361
433
|
* @async
|
|
362
|
-
* @param {?
|
|
434
|
+
* @param {?ReadEventActionParams<'getActionStepsCount'>} [params]
|
|
363
435
|
* @returns {Promise<bigint>}
|
|
364
436
|
*/
|
|
365
437
|
public async getActionStepsCount(
|
|
366
|
-
params?:
|
|
438
|
+
params?: ReadEventActionParams<'getActionStepsCount'>,
|
|
367
439
|
) {
|
|
368
440
|
const steps = await this.getActionSteps(params);
|
|
369
441
|
return steps.length;
|
|
@@ -374,17 +446,16 @@ export class EventAction extends DeployableTarget<
|
|
|
374
446
|
*
|
|
375
447
|
* @public
|
|
376
448
|
* @async
|
|
377
|
-
* @param {?
|
|
449
|
+
* @param {?ReadEventActionParams<'getActionClaimant'>} [params]
|
|
378
450
|
* @returns {Promise<ActionClaimant>}
|
|
379
451
|
*/
|
|
380
452
|
public async getActionClaimant(
|
|
381
|
-
params?:
|
|
453
|
+
params?: ReadEventActionParams<'getActionClaimant'>,
|
|
382
454
|
) {
|
|
383
455
|
const result = (await readEventActionGetActionClaimant(this._config, {
|
|
384
456
|
address: this.assertValidAddress(),
|
|
385
457
|
...this.optionallyAttachAccount(),
|
|
386
|
-
|
|
387
|
-
...(params as any),
|
|
458
|
+
...params,
|
|
388
459
|
})) as RawActionClaimant;
|
|
389
460
|
return _fromRawActionStep(result);
|
|
390
461
|
}
|
|
@@ -435,21 +506,11 @@ export class EventAction extends DeployableTarget<
|
|
|
435
506
|
*
|
|
436
507
|
* @public
|
|
437
508
|
* @async
|
|
438
|
-
* @param {?
|
|
439
|
-
* GetLogsParams<Abi, ContractEventName<Abi>> & {
|
|
440
|
-
* knownEvents?: Record<Hex, AbiEvent>;
|
|
441
|
-
* logs?: Log[];
|
|
442
|
-
* }} [params]
|
|
509
|
+
* @param {?TxParams} [params]
|
|
443
510
|
* @returns {Promise<boolean>}
|
|
444
511
|
*/
|
|
445
|
-
public async validateActionSteps(
|
|
446
|
-
|
|
447
|
-
GetLogsParams<Abi, ContractEventName<Abi>> & {
|
|
448
|
-
knownEvents?: Record<Hex, AbiEvent>;
|
|
449
|
-
logs?: Log[];
|
|
450
|
-
},
|
|
451
|
-
) {
|
|
452
|
-
const actionSteps = await this.getActionSteps(params);
|
|
512
|
+
public async validateActionSteps(params?: TxParams) {
|
|
513
|
+
const actionSteps = await this.getActionSteps();
|
|
453
514
|
for (const actionStep of actionSteps) {
|
|
454
515
|
if (!(await this.isActionStepValid(actionStep, params))) {
|
|
455
516
|
return false;
|
|
@@ -459,24 +520,45 @@ export class EventAction extends DeployableTarget<
|
|
|
459
520
|
}
|
|
460
521
|
|
|
461
522
|
/**
|
|
462
|
-
* Validates a single action step with a given criteria against logs.
|
|
463
|
-
* If logs are provided in the optional `params` argument, then those logs will be used instead of fetched with the configured client.
|
|
523
|
+
* Validates a single action step with a given criteria against logs or function calls.
|
|
524
|
+
* If logs are provided in the optional `params` argument, then those logs will be used instead of being fetched with the configured client.
|
|
525
|
+
* For functions a hash is required.
|
|
464
526
|
*
|
|
465
527
|
* @public
|
|
466
528
|
* @async
|
|
467
|
-
* @param {ActionStep} actionStep
|
|
468
|
-
* @param {?
|
|
469
|
-
* knownEvents?: Record<Hex, AbiEvent>;
|
|
470
|
-
* logs?: Log[];
|
|
471
|
-
* }} [params]
|
|
529
|
+
* @param {ActionStep} actionStep - The action step to validate. Can be a function of event step.
|
|
530
|
+
* @param {?TxParams & { chainId?: number }} [params] - Additional parameters for validation, including known events, logs, and chain ID.
|
|
472
531
|
* @returns {Promise<boolean>}
|
|
473
532
|
*/
|
|
474
533
|
public async isActionStepValid(
|
|
475
534
|
actionStep: ActionStep,
|
|
476
|
-
params?:
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
535
|
+
params?: TxParams & { chainId?: number },
|
|
536
|
+
) {
|
|
537
|
+
if (actionStep.signatureType === SignatureType.EVENT) {
|
|
538
|
+
return await this.isActionEventValid(actionStep, params);
|
|
539
|
+
}
|
|
540
|
+
if (actionStep.signatureType === SignatureType.FUNC) {
|
|
541
|
+
return await this.isActionFunctionValid(
|
|
542
|
+
actionStep,
|
|
543
|
+
params as ValidateFunctionStepParams,
|
|
544
|
+
);
|
|
545
|
+
}
|
|
546
|
+
return false;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Validates a single action event with a given criteria against logs.
|
|
551
|
+
* If logs are provided in the optional `params` argument, then those logs will be used instead of being fetched with the configured client.
|
|
552
|
+
*
|
|
553
|
+
* @public
|
|
554
|
+
* @async
|
|
555
|
+
* @param {ActionStep} actionStep - The action step containing the event to validate.
|
|
556
|
+
* @param {?ValidateEventStepParams & { chainId?: number }} [params] - Additional parameters for validation, including known events, logs, and chain ID.
|
|
557
|
+
* @returns {Promise<boolean>} Resolves to true if the action event is valid, throws if input is invalid, otherwise false.
|
|
558
|
+
*/
|
|
559
|
+
public async isActionEventValid(
|
|
560
|
+
actionStep: ActionStep,
|
|
561
|
+
params?: ValidateEventStepParams & { chainId?: number },
|
|
480
562
|
) {
|
|
481
563
|
const criteria = actionStep.actionParameter;
|
|
482
564
|
const signature = actionStep.signature;
|
|
@@ -487,9 +569,18 @@ export class EventAction extends DeployableTarget<
|
|
|
487
569
|
} else {
|
|
488
570
|
event = (events.abi as Record<Hex, AbiEvent>)[signature] as AbiEvent;
|
|
489
571
|
}
|
|
572
|
+
|
|
490
573
|
if (!event) {
|
|
491
574
|
throw new Error(`No known ABI for given event signature: ${signature}`);
|
|
492
575
|
}
|
|
576
|
+
|
|
577
|
+
if (this.isArraylikeIndexed(actionStep, event)) {
|
|
578
|
+
// If the field is indexed, we can't filter on it
|
|
579
|
+
throw new UnparseableAbiParamError(
|
|
580
|
+
actionStep.actionParameter.fieldIndex,
|
|
581
|
+
event,
|
|
582
|
+
);
|
|
583
|
+
}
|
|
493
584
|
const targetContract = actionStep.targetContract;
|
|
494
585
|
// Get all logs matching the event signature from the target contract
|
|
495
586
|
const logs =
|
|
@@ -502,69 +593,209 @@ export class EventAction extends DeployableTarget<
|
|
|
502
593
|
}));
|
|
503
594
|
if (!logs.length) return false;
|
|
504
595
|
for (let log of logs) {
|
|
505
|
-
if (!this.validateLogAgainstCriteria(criteria, log)) {
|
|
596
|
+
if (!this.validateLogAgainstCriteria(criteria, log as EventLogs[0])) {
|
|
506
597
|
return false;
|
|
507
598
|
}
|
|
508
599
|
}
|
|
509
600
|
return true;
|
|
510
601
|
}
|
|
602
|
+
/**
|
|
603
|
+
* Validates a single action function with a given criteria against the transaction input.
|
|
604
|
+
* If a transaction hash is provided in the optional `params` argument, then the transaction
|
|
605
|
+
* will be fetched and decoded using the configured client.
|
|
606
|
+
*
|
|
607
|
+
* @public
|
|
608
|
+
* @async
|
|
609
|
+
* @param {ActionStep} actionStep - The action step containing the function to validate.
|
|
610
|
+
* @param {?ValidateFunctionStepParams & { chainId?: number }} [params] - Additional parameters for validation, including known events, transaction hash, and chain ID.
|
|
611
|
+
* @returns {Promise<boolean>} Resolves to true if the action function is valid, throws if the inputs are invalid, otherwise false.
|
|
612
|
+
*/
|
|
613
|
+
public async isActionFunctionValid(
|
|
614
|
+
actionStep: ActionStep,
|
|
615
|
+
params?: ValidateFunctionStepParams & { chainId?: number },
|
|
616
|
+
) {
|
|
617
|
+
const criteria = actionStep.actionParameter;
|
|
618
|
+
const signature = trim(actionStep.signature);
|
|
619
|
+
if (!params || !params?.hash) {
|
|
620
|
+
// Should we return false in this case?
|
|
621
|
+
throw new Error('Hash is required for function validation');
|
|
622
|
+
}
|
|
623
|
+
const client = this._config.getClient({
|
|
624
|
+
chainId: params?.chainId,
|
|
625
|
+
}) as PublicClient;
|
|
626
|
+
// Fetch the transaction receipt and decode the function input using `viem` utilities
|
|
627
|
+
const transaction = await client.getTransaction({ hash: params.hash });
|
|
628
|
+
const func = (functions.abi as Record<Hex, AbiFunction>)[
|
|
629
|
+
signature
|
|
630
|
+
] as AbiFunction;
|
|
631
|
+
|
|
632
|
+
if (!func) {
|
|
633
|
+
throw new Error(
|
|
634
|
+
`No known ABI for given function signature: ${signature}`,
|
|
635
|
+
);
|
|
636
|
+
}
|
|
637
|
+
let decodedData;
|
|
638
|
+
try {
|
|
639
|
+
decodedData = decodeFunctionData({
|
|
640
|
+
abi: [func],
|
|
641
|
+
data: transaction.input,
|
|
642
|
+
});
|
|
643
|
+
} catch (e) {
|
|
644
|
+
throw new FunctionDataDecodeError([func], e as Error);
|
|
645
|
+
}
|
|
511
646
|
|
|
647
|
+
// Validate the criteria against decoded arguments using fieldIndex
|
|
648
|
+
const decodedArgs = decodedData.args;
|
|
649
|
+
|
|
650
|
+
if (!decodedArgs || !decodedData) return false;
|
|
651
|
+
|
|
652
|
+
if (
|
|
653
|
+
!this.validateFunctionAgainstCriteria(
|
|
654
|
+
criteria,
|
|
655
|
+
decodedArgs as (string | bigint)[],
|
|
656
|
+
)
|
|
657
|
+
) {
|
|
658
|
+
return false;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
return true;
|
|
662
|
+
}
|
|
512
663
|
/**
|
|
513
|
-
* Validates a
|
|
664
|
+
* Validates a field against a given criteria.
|
|
514
665
|
*
|
|
515
666
|
* @param {Criteria} criteria - The criteria to validate against.
|
|
516
|
-
* @param {
|
|
517
|
-
* @returns {boolean} - Returns true if the
|
|
667
|
+
* @param {string | bigint} fieldValue - The field value to validate.
|
|
668
|
+
* @returns {Promise<boolean>} - Returns true if the field passes the criteria, false otherwise.
|
|
518
669
|
*/
|
|
519
|
-
public
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
670
|
+
public validateFieldAgainstCriteria(
|
|
671
|
+
criteria: Criteria,
|
|
672
|
+
fieldValue: string | bigint | Hex,
|
|
673
|
+
input:
|
|
674
|
+
| { log: EventLogs[0] }
|
|
675
|
+
| { decodedArgs: readonly (string | bigint)[] },
|
|
676
|
+
): boolean {
|
|
524
677
|
// Type narrow based on criteria.filterType
|
|
525
678
|
switch (criteria.filterType) {
|
|
526
679
|
case FilterType.EQUAL:
|
|
527
680
|
if (criteria.fieldType === PrimitiveType.ADDRESS) {
|
|
528
|
-
return isAddressEqual(
|
|
529
|
-
criteria.filterData,
|
|
530
|
-
`0x${fieldValue.slice(-40)}`,
|
|
531
|
-
);
|
|
681
|
+
return isAddressEqual(criteria.filterData, fieldValue as Address);
|
|
532
682
|
}
|
|
533
683
|
return fieldValue === criteria.filterData;
|
|
534
684
|
|
|
535
685
|
case FilterType.NOT_EQUAL:
|
|
536
|
-
if (criteria.fieldType === PrimitiveType.ADDRESS) {
|
|
537
|
-
return !isAddressEqual(
|
|
538
|
-
criteria.filterData,
|
|
539
|
-
`0x${fieldValue.slice(-40)}`,
|
|
540
|
-
);
|
|
541
|
-
}
|
|
542
686
|
return fieldValue !== criteria.filterData;
|
|
543
687
|
|
|
544
688
|
case FilterType.GREATER_THAN:
|
|
545
689
|
if (criteria.fieldType === PrimitiveType.UINT) {
|
|
546
690
|
return BigInt(fieldValue) > BigInt(criteria.filterData);
|
|
547
691
|
}
|
|
548
|
-
throw new InvalidNumericalCriteriaError({
|
|
692
|
+
throw new InvalidNumericalCriteriaError({
|
|
693
|
+
...input,
|
|
694
|
+
criteria,
|
|
695
|
+
fieldValue,
|
|
696
|
+
});
|
|
549
697
|
|
|
550
698
|
case FilterType.LESS_THAN:
|
|
551
699
|
if (criteria.fieldType === PrimitiveType.UINT) {
|
|
552
700
|
return BigInt(fieldValue) < BigInt(criteria.filterData);
|
|
553
701
|
}
|
|
554
|
-
throw new InvalidNumericalCriteriaError({
|
|
702
|
+
throw new InvalidNumericalCriteriaError({
|
|
703
|
+
...input,
|
|
704
|
+
criteria,
|
|
705
|
+
fieldValue,
|
|
706
|
+
});
|
|
555
707
|
|
|
556
708
|
case FilterType.CONTAINS:
|
|
557
709
|
if (
|
|
558
710
|
criteria.fieldType === PrimitiveType.BYTES ||
|
|
559
711
|
criteria.fieldType === PrimitiveType.STRING
|
|
560
712
|
) {
|
|
561
|
-
|
|
713
|
+
let substring;
|
|
714
|
+
if (criteria.fieldType === PrimitiveType.STRING) {
|
|
715
|
+
substring = fromHex(criteria.filterData, 'string');
|
|
716
|
+
} else {
|
|
717
|
+
// truncate the `0x` prefix
|
|
718
|
+
substring = criteria.filterData.slice(2);
|
|
719
|
+
}
|
|
720
|
+
return (fieldValue as string).includes(substring);
|
|
721
|
+
}
|
|
722
|
+
throw new FieldValueNotComparableError({
|
|
723
|
+
...input,
|
|
724
|
+
criteria,
|
|
725
|
+
fieldValue,
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
case FilterType.REGEX:
|
|
729
|
+
if (typeof fieldValue !== 'string') {
|
|
730
|
+
throw new FieldValueNotComparableError({
|
|
731
|
+
...input,
|
|
732
|
+
criteria,
|
|
733
|
+
fieldValue,
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
if (criteria.fieldType === PrimitiveType.STRING) {
|
|
738
|
+
// fieldValue is decoded by the ABI
|
|
739
|
+
const regexString = fromHex(criteria.filterData, 'string');
|
|
740
|
+
return new RegExp(regexString).test(fieldValue);
|
|
562
741
|
}
|
|
563
|
-
throw new FieldValueNotComparableError({ log, criteria, fieldValue });
|
|
564
742
|
|
|
565
743
|
default:
|
|
566
|
-
throw new UnrecognizedFilterTypeError({
|
|
744
|
+
throw new UnrecognizedFilterTypeError({
|
|
745
|
+
...input,
|
|
746
|
+
criteria,
|
|
747
|
+
fieldValue,
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* Validates a {@link Log} against a given criteria.
|
|
754
|
+
*
|
|
755
|
+
* @param {Criteria} criteria - The criteria to validate against.
|
|
756
|
+
* @param {Log} log - The Viem event log.
|
|
757
|
+
* @returns {Promise<boolean>} - Returns true if the log passes the criteria, false otherwise.
|
|
758
|
+
*/
|
|
759
|
+
public validateLogAgainstCriteria(
|
|
760
|
+
criteria: Criteria,
|
|
761
|
+
log: EventLogs[0],
|
|
762
|
+
): boolean {
|
|
763
|
+
if (!Array.isArray(log.args) || log.args.length <= criteria.fieldIndex) {
|
|
764
|
+
throw new DecodedArgsMalformedError({
|
|
765
|
+
log,
|
|
766
|
+
criteria,
|
|
767
|
+
fieldValue: undefined,
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
const fieldValue = log.args.at(criteria.fieldIndex);
|
|
772
|
+
if (fieldValue === undefined) {
|
|
773
|
+
throw new FieldValueUndefinedError({ log, criteria, fieldValue });
|
|
567
774
|
}
|
|
775
|
+
return this.validateFieldAgainstCriteria(criteria, fieldValue, { log });
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
* Validates a function's decoded arguments against a given criteria.
|
|
780
|
+
*
|
|
781
|
+
* @param {Criteria} criteria - The criteria to validate against.
|
|
782
|
+
* @param {unknown[]} decodedArgs - The decoded arguments of the function call.
|
|
783
|
+
* @returns {Promise<boolean>} - Returns true if the decoded argument passes the criteria, false otherwise.
|
|
784
|
+
*/
|
|
785
|
+
public validateFunctionAgainstCriteria(
|
|
786
|
+
criteria: Criteria,
|
|
787
|
+
decodedArgs: readonly (string | bigint)[],
|
|
788
|
+
): boolean {
|
|
789
|
+
const fieldValue = decodedArgs[criteria.fieldIndex];
|
|
790
|
+
if (fieldValue === undefined) {
|
|
791
|
+
throw new FieldValueUndefinedError({
|
|
792
|
+
criteria,
|
|
793
|
+
fieldValue,
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
return this.validateFieldAgainstCriteria(criteria, fieldValue, {
|
|
797
|
+
decodedArgs,
|
|
798
|
+
});
|
|
568
799
|
}
|
|
569
800
|
|
|
570
801
|
/**
|
|
@@ -615,6 +846,17 @@ export class EventAction extends DeployableTarget<
|
|
|
615
846
|
...this.optionallyAttachAccount(options.account),
|
|
616
847
|
};
|
|
617
848
|
}
|
|
849
|
+
|
|
850
|
+
public isArraylikeIndexed(step: ActionStep, event: AbiEvent) {
|
|
851
|
+
if (
|
|
852
|
+
(step.actionParameter.fieldType === PrimitiveType.STRING ||
|
|
853
|
+
step.actionParameter.fieldType === PrimitiveType.BYTES) &&
|
|
854
|
+
event.inputs[step.actionParameter.fieldIndex]?.indexed
|
|
855
|
+
) {
|
|
856
|
+
return true;
|
|
857
|
+
}
|
|
858
|
+
return false;
|
|
859
|
+
}
|
|
618
860
|
}
|
|
619
861
|
|
|
620
862
|
function _dedupeActionSteps(_steps: ActionStep[]): ActionStep[] {
|
|
@@ -52,7 +52,7 @@ describe('AllowList', () => {
|
|
|
52
52
|
).toBeInstanceOf(SimpleAllowList);
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
test('can automatically instantiate
|
|
55
|
+
test('can automatically instantiate SimpleDenyList given an address', async () => {
|
|
56
56
|
const _allowList = await loadFixture(freshDenyList(fixtures));
|
|
57
57
|
expect(
|
|
58
58
|
await allowListFromAddress(
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
zeroAddress,
|
|
17
17
|
zeroHash,
|
|
18
18
|
} from 'viem';
|
|
19
|
+
import { SimpleAllowList as SimpleAllowListBases } from '../../dist/deployments.json';
|
|
19
20
|
import type {
|
|
20
21
|
DeployableOptions,
|
|
21
22
|
GenericDeployableParams,
|
|
@@ -92,10 +93,12 @@ export class SimpleAllowList extends DeployableTarget<
|
|
|
92
93
|
*
|
|
93
94
|
* @public
|
|
94
95
|
* @static
|
|
95
|
-
* @type {Address}
|
|
96
|
+
* @type {Record<number, Address>}
|
|
96
97
|
*/
|
|
97
|
-
public static override
|
|
98
|
-
|
|
98
|
+
public static override bases: Record<number, Address> = {
|
|
99
|
+
...(SimpleAllowListBases as Record<number, Address>),
|
|
100
|
+
31337: import.meta.env.VITE_SIMPLE_ALLOWLIST_BASE,
|
|
101
|
+
};
|
|
99
102
|
/**
|
|
100
103
|
* @inheritdoc
|
|
101
104
|
*
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
zeroAddress,
|
|
15
15
|
zeroHash,
|
|
16
16
|
} from 'viem';
|
|
17
|
+
import { SimpleDenyList as SimpleDenyListBases } from '../../dist/deployments.json';
|
|
17
18
|
import type {
|
|
18
19
|
DeployableOptions,
|
|
19
20
|
GenericDeployableParams,
|
|
@@ -83,10 +84,12 @@ export class SimpleDenyList<
|
|
|
83
84
|
*
|
|
84
85
|
* @public
|
|
85
86
|
* @static
|
|
86
|
-
* @type {Address}
|
|
87
|
+
* @type {Record<number, Address>}
|
|
87
88
|
*/
|
|
88
|
-
public static override
|
|
89
|
-
|
|
89
|
+
public static override bases: Record<number, Address> = {
|
|
90
|
+
...(SimpleDenyListBases as Record<number, Address>),
|
|
91
|
+
31337: import.meta.env.VITE_SIMPLE_DENYLIST_BASE,
|
|
92
|
+
};
|
|
90
93
|
/**
|
|
91
94
|
* @inheritdoc
|
|
92
95
|
*
|