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