@boostxyz/sdk 0.0.0-alpha.17 → 0.0.0-alpha.19

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.
Files changed (205) hide show
  1. package/dist/Actions/Action.cjs +1 -1
  2. package/dist/Actions/Action.cjs.map +1 -1
  3. package/dist/Actions/Action.js +13 -13
  4. package/dist/Actions/ContractAction.d.ts +9 -9
  5. package/dist/Actions/ContractAction.d.ts.map +1 -1
  6. package/dist/Actions/ERC721MintAction.d.ts +12 -12
  7. package/dist/Actions/ERC721MintAction.d.ts.map +1 -1
  8. package/dist/Actions/EventAction.cjs +1 -1
  9. package/dist/Actions/EventAction.cjs.map +1 -1
  10. package/dist/Actions/EventAction.d.ts +32 -49
  11. package/dist/Actions/EventAction.d.ts.map +1 -1
  12. package/dist/Actions/EventAction.js +13 -962
  13. package/dist/Actions/EventAction.js.map +1 -1
  14. package/dist/AllowLists/AllowList.cjs +1 -1
  15. package/dist/AllowLists/AllowList.js +3 -3
  16. package/dist/AllowLists/SimpleAllowList.cjs +1 -1
  17. package/dist/AllowLists/SimpleAllowList.cjs.map +1 -1
  18. package/dist/AllowLists/SimpleAllowList.d.ts +5 -5
  19. package/dist/AllowLists/SimpleAllowList.js +24 -24
  20. package/dist/AllowLists/SimpleAllowList.js.map +1 -1
  21. package/dist/AllowLists/SimpleDenyList.cjs +1 -1
  22. package/dist/AllowLists/SimpleDenyList.d.ts +6 -6
  23. package/dist/AllowLists/SimpleDenyList.js +3 -3
  24. package/dist/Auth/PassthroughAuth.cjs +1 -1
  25. package/dist/Auth/PassthroughAuth.js +1 -1
  26. package/dist/Boost.cjs.map +1 -1
  27. package/dist/Boost.d.ts +18 -0
  28. package/dist/Boost.d.ts.map +1 -1
  29. package/dist/Boost.js.map +1 -1
  30. package/dist/BoostCore-BiPwp6SR.cjs +3 -0
  31. package/dist/BoostCore-BiPwp6SR.cjs.map +1 -0
  32. package/dist/BoostCore-kwoUw7YE.js +1477 -0
  33. package/dist/BoostCore-kwoUw7YE.js.map +1 -0
  34. package/dist/BoostCore.cjs +1 -2
  35. package/dist/BoostCore.cjs.map +1 -1
  36. package/dist/BoostCore.d.ts +86 -36
  37. package/dist/BoostCore.d.ts.map +1 -1
  38. package/dist/BoostCore.js +29 -1273
  39. package/dist/BoostCore.js.map +1 -1
  40. package/dist/BoostRegistry.cjs +1 -1
  41. package/dist/BoostRegistry.cjs.map +1 -1
  42. package/dist/BoostRegistry.d.ts +25 -19
  43. package/dist/BoostRegistry.d.ts.map +1 -1
  44. package/dist/BoostRegistry.js +30 -29
  45. package/dist/BoostRegistry.js.map +1 -1
  46. package/dist/Budgets/Budget.cjs +1 -1
  47. package/dist/Budgets/Budget.js +2 -2
  48. package/dist/Budgets/ManagedBudget.cjs +1 -1
  49. package/dist/Budgets/ManagedBudget.cjs.map +1 -1
  50. package/dist/Budgets/ManagedBudget.d.ts +18 -18
  51. package/dist/Budgets/ManagedBudget.js +48 -48
  52. package/dist/Budgets/ManagedBudget.js.map +1 -1
  53. package/dist/Budgets/VestingBudget.d.ts +23 -23
  54. package/dist/Deployable/Contract.cjs +1 -1
  55. package/dist/Deployable/Contract.cjs.map +1 -1
  56. package/dist/Deployable/Contract.d.ts +4 -5
  57. package/dist/Deployable/Contract.d.ts.map +1 -1
  58. package/dist/Deployable/Contract.js +4 -5
  59. package/dist/Deployable/Contract.js.map +1 -1
  60. package/dist/Deployable/Deployable.cjs.map +1 -1
  61. package/dist/Deployable/Deployable.d.ts +1 -1
  62. package/dist/Deployable/Deployable.js +1 -1
  63. package/dist/Deployable/Deployable.js.map +1 -1
  64. package/dist/Deployable/DeployableTarget.cjs +1 -1
  65. package/dist/Deployable/DeployableTarget.cjs.map +1 -1
  66. package/dist/Deployable/DeployableTarget.d.ts +5 -5
  67. package/dist/Deployable/DeployableTarget.js +6 -6
  68. package/dist/Deployable/DeployableTarget.js.map +1 -1
  69. package/dist/Deployable/DeployableTargetWithRBAC.cjs +1 -1
  70. package/dist/Deployable/DeployableTargetWithRBAC.cjs.map +1 -1
  71. package/dist/Deployable/DeployableTargetWithRBAC.d.ts +15 -15
  72. package/dist/Deployable/DeployableTargetWithRBAC.js +33 -33
  73. package/dist/Deployable/DeployableTargetWithRBAC.js.map +1 -1
  74. package/dist/EventAction-D5tnm00s.js +1355 -0
  75. package/dist/EventAction-D5tnm00s.js.map +1 -0
  76. package/dist/EventAction-DBDRaG4A.cjs +2 -0
  77. package/dist/EventAction-DBDRaG4A.cjs.map +1 -0
  78. package/dist/{Incentive-DJf-vdyL.js → Incentive-Bp8Sez7M.js} +61 -62
  79. package/dist/Incentive-Bp8Sez7M.js.map +1 -0
  80. package/dist/{Incentive-DNwROd1r.cjs → Incentive-Djnzseoj.cjs} +2 -2
  81. package/dist/Incentive-Djnzseoj.cjs.map +1 -0
  82. package/dist/Incentives/AllowListIncentive.cjs +1 -1
  83. package/dist/Incentives/AllowListIncentive.cjs.map +1 -1
  84. package/dist/Incentives/AllowListIncentive.d.ts +12 -12
  85. package/dist/Incentives/AllowListIncentive.js +19 -19
  86. package/dist/Incentives/AllowListIncentive.js.map +1 -1
  87. package/dist/Incentives/CGDAIncentive.cjs +1 -1
  88. package/dist/Incentives/CGDAIncentive.cjs.map +1 -1
  89. package/dist/Incentives/CGDAIncentive.d.ts +15 -15
  90. package/dist/Incentives/CGDAIncentive.js +18 -18
  91. package/dist/Incentives/CGDAIncentive.js.map +1 -1
  92. package/dist/Incentives/ERC1155Incentive.d.ts +30 -30
  93. package/dist/Incentives/ERC20Incentive.cjs +1 -1
  94. package/dist/Incentives/ERC20Incentive.cjs.map +1 -1
  95. package/dist/Incentives/ERC20Incentive.d.ts +23 -23
  96. package/dist/Incentives/ERC20Incentive.js +25 -25
  97. package/dist/Incentives/ERC20Incentive.js.map +1 -1
  98. package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts +523 -0
  99. package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts.map +1 -0
  100. package/dist/Incentives/ERC20VariableIncentive.d.ts +19 -19
  101. package/dist/Incentives/Incentive.cjs +1 -1
  102. package/dist/Incentives/Incentive.d.ts +3 -3
  103. package/dist/Incentives/Incentive.d.ts.map +1 -1
  104. package/dist/Incentives/Incentive.js +3 -3
  105. package/dist/Incentives/PointsIncentive.cjs +1 -1
  106. package/dist/Incentives/PointsIncentive.cjs.map +1 -1
  107. package/dist/Incentives/PointsIncentive.d.ts +14 -14
  108. package/dist/Incentives/PointsIncentive.js +21 -21
  109. package/dist/Incentives/PointsIncentive.js.map +1 -1
  110. package/dist/{SimpleDenyList-DMlUkmAn.cjs → SimpleDenyList-BwfNjRsg.cjs} +2 -2
  111. package/dist/SimpleDenyList-BwfNjRsg.cjs.map +1 -0
  112. package/dist/{SimpleDenyList-DvUvmOeE.js → SimpleDenyList-Cn5WpNn0.js} +9 -9
  113. package/dist/SimpleDenyList-Cn5WpNn0.js.map +1 -0
  114. package/dist/Validators/SignerValidator.cjs +1 -1
  115. package/dist/Validators/SignerValidator.cjs.map +1 -1
  116. package/dist/Validators/SignerValidator.d.ts +14 -14
  117. package/dist/Validators/SignerValidator.js +19 -19
  118. package/dist/Validators/SignerValidator.js.map +1 -1
  119. package/dist/Validators/Validator.cjs +1 -1
  120. package/dist/Validators/Validator.cjs.map +1 -1
  121. package/dist/Validators/Validator.d.ts +1 -1
  122. package/dist/Validators/Validator.js +6 -6
  123. package/dist/Validators/Validator.js.map +1 -1
  124. package/dist/claiming.cjs.map +1 -1
  125. package/dist/claiming.d.ts +1 -1
  126. package/dist/claiming.js.map +1 -1
  127. package/dist/componentInterfaces-D09mhzxO.cjs +2 -0
  128. package/dist/componentInterfaces-D09mhzxO.cjs.map +1 -0
  129. package/dist/componentInterfaces-RXBMI5yH.js +14 -0
  130. package/dist/componentInterfaces-RXBMI5yH.js.map +1 -0
  131. package/dist/deployments-BM42vImE.js +43 -0
  132. package/dist/deployments-BM42vImE.js.map +1 -0
  133. package/dist/deployments-CMdF5uEC.cjs +2 -0
  134. package/dist/deployments-CMdF5uEC.cjs.map +1 -0
  135. package/dist/deployments.json +15 -12
  136. package/dist/errors.cjs +1 -1
  137. package/dist/errors.cjs.map +1 -1
  138. package/dist/errors.d.ts +132 -0
  139. package/dist/errors.d.ts.map +1 -1
  140. package/dist/errors.js +122 -36
  141. package/dist/errors.js.map +1 -1
  142. package/dist/generated-B0tk-c9b.cjs +3 -0
  143. package/dist/generated-B0tk-c9b.cjs.map +1 -0
  144. package/dist/{generated-C_7Jx3YG.js → generated-B7VaSah4.js} +631 -343
  145. package/dist/generated-B7VaSah4.js.map +1 -0
  146. package/dist/index.cjs +1 -1
  147. package/dist/index.d.ts +1 -0
  148. package/dist/index.d.ts.map +1 -1
  149. package/dist/index.js +135 -126
  150. package/dist/transfers.cjs.map +1 -1
  151. package/dist/transfers.d.ts +1 -1
  152. package/dist/transfers.js.map +1 -1
  153. package/dist/utils.cjs.map +1 -1
  154. package/dist/utils.d.ts +1 -1
  155. package/dist/utils.js.map +1 -1
  156. package/package.json +5 -5
  157. package/src/Actions/ContractAction.ts +9 -10
  158. package/src/Actions/ERC721MintAction.ts +12 -13
  159. package/src/Actions/EventAction.test.ts +45 -54
  160. package/src/Actions/EventAction.ts +100 -100
  161. package/src/AllowLists/SimpleAllowList.ts +5 -5
  162. package/src/AllowLists/SimpleDenyList.ts +6 -6
  163. package/src/Boost.ts +19 -0
  164. package/src/BoostCore.test.ts +117 -1
  165. package/src/BoostCore.ts +121 -57
  166. package/src/BoostRegistry.ts +29 -21
  167. package/src/Budgets/ManagedBudget.ts +18 -18
  168. package/src/Budgets/VestingBudget.ts +23 -23
  169. package/src/Deployable/Contract.ts +4 -5
  170. package/src/Deployable/Deployable.ts +1 -1
  171. package/src/Deployable/DeployableTarget.ts +5 -5
  172. package/src/Deployable/DeployableTargetWithRBAC.ts +15 -15
  173. package/src/Incentives/AllowListIncentive.ts +12 -12
  174. package/src/Incentives/CGDAIncentive.ts +15 -15
  175. package/src/Incentives/ERC1155Incentive.ts +26 -26
  176. package/src/Incentives/ERC20Incentive.ts +23 -23
  177. package/src/Incentives/ERC20VariableCriteriaIncentive.test.ts +184 -0
  178. package/src/Incentives/ERC20VariableCriteriaIncentive.ts +309 -0
  179. package/src/Incentives/ERC20VariableIncentive.ts +19 -19
  180. package/src/Incentives/Incentive.ts +6 -5
  181. package/src/Incentives/PointsIncentive.test.ts +21 -21
  182. package/src/Incentives/PointsIncentive.ts +14 -14
  183. package/src/Validators/SignerValidator.ts +14 -14
  184. package/src/Validators/Validator.ts +1 -1
  185. package/src/claiming.ts +1 -1
  186. package/src/errors.ts +165 -0
  187. package/src/index.test.ts +117 -33
  188. package/src/index.ts +1 -0
  189. package/src/transfers.ts +1 -1
  190. package/src/utils.ts +1 -1
  191. package/dist/Incentive-DJf-vdyL.js.map +0 -1
  192. package/dist/Incentive-DNwROd1r.cjs.map +0 -1
  193. package/dist/SimpleDenyList-DMlUkmAn.cjs.map +0 -1
  194. package/dist/SimpleDenyList-DvUvmOeE.js.map +0 -1
  195. package/dist/componentInterfaces-BPVR_Ykd.js +0 -13
  196. package/dist/componentInterfaces-BPVR_Ykd.js.map +0 -1
  197. package/dist/componentInterfaces-BfppSIl4.cjs +0 -2
  198. package/dist/componentInterfaces-BfppSIl4.cjs.map +0 -1
  199. package/dist/deployments-BvFcK_eR.js +0 -40
  200. package/dist/deployments-BvFcK_eR.js.map +0 -1
  201. package/dist/deployments-Ho4PnGCS.cjs +0 -2
  202. package/dist/deployments-Ho4PnGCS.cjs.map +0 -1
  203. package/dist/generated-CMQ6ZC2_.cjs +0 -3
  204. package/dist/generated-CMQ6ZC2_.cjs.map +0 -1
  205. package/dist/generated-C_7Jx3YG.js.map +0 -1
@@ -21,12 +21,13 @@ import {
21
21
  type Hex,
22
22
  type Log,
23
23
  type PublicClient,
24
+ type Transaction,
25
+ decodeEventLog,
24
26
  decodeFunctionData,
25
27
  encodeAbiParameters,
26
28
  fromHex,
27
29
  isAddressEqual,
28
30
  } from 'viem';
29
- import { getLogs } from 'viem/actions';
30
31
  import { EventAction as EventActionBases } from '../../dist/deployments.json';
31
32
  import type {
32
33
  DeployableOptions,
@@ -43,6 +44,8 @@ import {
43
44
  TooManyEventActionStepsProvidedError,
44
45
  UnparseableAbiParamError,
45
46
  UnrecognizedFilterTypeError,
47
+ ValidationAbiMissingError,
48
+ ValidationLogsMissingError,
46
49
  } from '../errors';
47
50
  import {
48
51
  type GetLogsParams,
@@ -214,38 +217,19 @@ export interface ActionStep {
214
217
  }
215
218
 
216
219
  /**
217
- * Parameters for validating an event step.
220
+ * Parameters for validating an action step.
218
221
  *
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]
222
+ * @typedef {Object} ValidateActionStepParams
223
+ * @property {Record<Hex, AbiEvent>} [knownEvents] - Optional record of known events, keyed by their hex signature.
224
+ * @property {AbiEvent} [event] - Optional ABI event definition.
225
+ * @property {EventLogs} [logs] - Event logs to validate against. Required if 'hash' is not provided.
226
+ * @property {Hex} [hash] - Transaction hash to validate against. Required if 'logs' is not provided.
227
+ * @property {number} [chainId] - Chain ID for the transaction. Required if 'hash' is provided.
247
228
  */
248
- export type ValidateFunctionStepParams = GetTransactionParameters;
229
+ export type ValidateActionStepParams = {
230
+ knownEvents?: Record<Hex, AbiEvent>;
231
+ event?: AbiEvent;
232
+ } & ({ logs: EventLogs } | { hash: Hex; chainId: number });
249
233
 
250
234
  /**
251
235
  * You can either supply a simplified version of the payload, or one that explicitly declares action steps.
@@ -347,8 +331,6 @@ export type ReadEventActionParams<
347
331
  fnName extends ContractFunctionName<typeof eventActionAbi, 'pure' | 'view'>,
348
332
  > = ReadParams<typeof eventActionAbi, fnName>;
349
333
 
350
- type TxParams = ValidateEventStepParams | ValidateFunctionStepParams;
351
-
352
334
  /**
353
335
  * A generic event action
354
336
  *
@@ -465,7 +447,7 @@ export class EventAction extends DeployableTarget<
465
447
  * @public
466
448
  * @async
467
449
  * @param {Hex} data
468
- * @param {?WriteParams<typeof eventActionAbi, 'execute'>} [params]
450
+ * @param {?WriteParams} [params]
469
451
  * @returns {Promise<readonly [boolean, `0x${string}`]>}
470
452
  */
471
453
  public async execute(
@@ -481,8 +463,8 @@ export class EventAction extends DeployableTarget<
481
463
  * @public
482
464
  * @async
483
465
  * @param {Hex} data
484
- * @param {?WriteParams<typeof eventActionAbi, 'execute'>} [params]
485
- * @returns {unknown}
466
+ * @param {?WriteParams} [params]
467
+ * @returns {Promise<{ hash: `0x${string}`; result: readonly [boolean, `0x${string}`]; }>}
486
468
  */
487
469
  public async executeRaw(
488
470
  data: Hex,
@@ -505,10 +487,10 @@ export class EventAction extends DeployableTarget<
505
487
  *
506
488
  * @public
507
489
  * @async
508
- * @param {?TxParams} [params]
490
+ * @param ValidateActionStepParams params
509
491
  * @returns {Promise<boolean>}
510
492
  */
511
- public async validateActionSteps(params?: TxParams) {
493
+ public async validateActionSteps(params: ValidateActionStepParams) {
512
494
  const actionSteps = await this.getActionSteps();
513
495
  for (const actionStep of actionSteps) {
514
496
  if (!(await this.isActionStepValid(actionStep, params))) {
@@ -526,21 +508,75 @@ export class EventAction extends DeployableTarget<
526
508
  * @public
527
509
  * @async
528
510
  * @param {ActionStep} actionStep - The action step to validate. Can be a function of event step.
529
- * @param {?TxParams & { chainId?: number }} [params] - Additional parameters for validation, including known events, logs, and chain ID.
511
+ * @param {ValidateActionStepParams} params - Additional parameters for validation, including hash, known events, logs, and chain ID.
530
512
  * @returns {Promise<boolean>}
531
513
  */
532
514
  public async isActionStepValid(
533
515
  actionStep: ActionStep,
534
- params?: TxParams & { chainId?: number },
516
+ params: ValidateActionStepParams,
535
517
  ) {
536
518
  if (actionStep.signatureType === SignatureType.EVENT) {
537
- return await this.isActionEventValid(actionStep, params);
519
+ const signature = actionStep.signature;
520
+ let event: AbiEvent;
521
+ // Lookup ABI based on event signature
522
+ if (params.knownEvents) {
523
+ event = params.knownEvents?.[signature] as AbiEvent;
524
+ } else {
525
+ event = (events.abi as Record<Hex, AbiEvent>)[signature] as AbiEvent;
526
+ }
527
+
528
+ if (!event) {
529
+ throw new ValidationAbiMissingError(signature);
530
+ }
531
+
532
+ if (this.isArraylikeIndexed(actionStep, event)) {
533
+ // If the field is indexed, we can't filter on it
534
+ throw new UnparseableAbiParamError(
535
+ actionStep.actionParameter.fieldIndex,
536
+ event,
537
+ );
538
+ }
539
+
540
+ params.event = event;
541
+
542
+ // Use the provided logs, no need to fetch receipt
543
+ if ('logs' in params) {
544
+ return this.isActionEventValid(actionStep, {
545
+ ...params,
546
+ });
547
+ }
548
+
549
+ const client = this._config.getClient({
550
+ chainId: params.chainId,
551
+ }) as PublicClient;
552
+ const receipt = await client.getTransactionReceipt({
553
+ hash: params.hash,
554
+ });
555
+ const decodedLogs = receipt.logs.map((log) => {
556
+ const { eventName, args } = decodeEventLog({
557
+ abi: [event],
558
+ data: log.data,
559
+ topics: log.topics,
560
+ });
561
+
562
+ return { ...log, eventName, args };
563
+ });
564
+
565
+ return this.isActionEventValid(actionStep, {
566
+ logs: decodedLogs,
567
+ ...params,
568
+ });
538
569
  }
539
570
  if (actionStep.signatureType === SignatureType.FUNC) {
540
- return await this.isActionFunctionValid(
541
- actionStep,
542
- params as ValidateFunctionStepParams,
543
- );
571
+ if ('hash' in params && 'chainId' in params) {
572
+ const client = this._config.getClient({
573
+ chainId: params.chainId,
574
+ }) as PublicClient;
575
+ const transaction = await client.getTransaction({
576
+ hash: params.hash,
577
+ });
578
+ return this.isActionFunctionValid(actionStep, transaction);
579
+ }
544
580
  }
545
581
  return false;
546
582
  }
@@ -552,88 +588,49 @@ export class EventAction extends DeployableTarget<
552
588
  * @public
553
589
  * @async
554
590
  * @param {ActionStep} actionStep - The action step containing the event to validate.
555
- * @param {?ValidateEventStepParams & { chainId?: number }} [params] - Additional parameters for validation, including known events, logs, and chain ID.
591
+ * @param {ValidateActionStepParams} params - Additional parameters for validation, including known events and logs
556
592
  * @returns {Promise<boolean>} Resolves to true if the action event is valid, throws if input is invalid, otherwise false.
557
593
  */
558
- public async isActionEventValid(
594
+ public isActionEventValid(
559
595
  actionStep: ActionStep,
560
- params?: ValidateEventStepParams & { chainId?: number },
596
+ params: ValidateActionStepParams,
561
597
  ) {
562
- const criteria = actionStep.actionParameter;
563
- const signature = actionStep.signature;
564
- let event: AbiEvent;
565
- // Lookup ABI based on event signature
566
- if (params?.knownEvents) {
567
- event = params.knownEvents[signature] as AbiEvent;
568
- } else {
569
- event = (events.abi as Record<Hex, AbiEvent>)[signature] as AbiEvent;
570
- }
571
-
572
- if (!event) {
573
- throw new Error(`No known ABI for given event signature: ${signature}`);
598
+ if (!('logs' in params)) {
599
+ throw new ValidationLogsMissingError();
574
600
  }
575
-
576
- if (this.isArraylikeIndexed(actionStep, event)) {
577
- // If the field is indexed, we can't filter on it
578
- throw new UnparseableAbiParamError(
579
- actionStep.actionParameter.fieldIndex,
580
- event,
581
- );
582
- }
583
- const targetContract = actionStep.targetContract;
584
- // Get all logs matching the event signature from the target contract
585
- const logs =
586
- params?.logs ||
587
- (await getLogs(this._config.getClient({ chainId: params?.chainId }), {
588
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
589
- ...(params as any),
590
- address: targetContract,
591
- event,
592
- }));
601
+ const criteria = actionStep.actionParameter;
602
+ const logs = params.logs;
593
603
  if (!logs.length) return false;
594
604
  for (let log of logs) {
595
- if (!this.validateLogAgainstCriteria(criteria, log as EventLogs[0])) {
596
- return false;
605
+ if (this.validateLogAgainstCriteria(criteria, log)) {
606
+ return true;
597
607
  }
598
608
  }
599
- return true;
609
+ return false;
600
610
  }
601
611
  /**
602
612
  * Validates a single action function with a given criteria against the transaction input.
603
- * If a transaction hash is provided in the optional `params` argument, then the transaction
604
- * will be fetched and decoded using the configured client.
605
613
  *
606
614
  * @public
607
615
  * @async
608
616
  * @param {ActionStep} actionStep - The action step containing the function to validate.
609
- * @param {?ValidateFunctionStepParams & { chainId?: number }} [params] - Additional parameters for validation, including known events, transaction hash, and chain ID.
617
+ * @param {Transaction} transaction - The transaction that will be validated against.
610
618
  * @returns {Promise<boolean>} Resolves to true if the action function is valid, throws if the inputs are invalid, otherwise false.
611
619
  */
612
- public async isActionFunctionValid(
620
+ public isActionFunctionValid(
613
621
  actionStep: ActionStep,
614
- params?: ValidateFunctionStepParams & { chainId?: number },
622
+ transaction: Transaction,
615
623
  ) {
616
624
  const criteria = actionStep.actionParameter;
617
625
  let signature = actionStep.signature;
618
626
 
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
627
  const func = (functions.abi as Record<Hex, AbiFunction>)[
629
628
  signature
630
629
  ] as AbiFunction;
631
-
632
630
  if (!func) {
633
- throw new Error(
634
- `No known ABI for given function signature: ${signature}`,
635
- );
631
+ throw new ValidationAbiMissingError(signature);
636
632
  }
633
+
637
634
  let decodedData;
638
635
  try {
639
636
  decodedData = decodeFunctionData({
@@ -664,7 +661,10 @@ export class EventAction extends DeployableTarget<
664
661
  * Validates a field against a given criteria.
665
662
  *
666
663
  * @param {Criteria} criteria - The criteria to validate against.
667
- * @param {string | bigint} fieldValue - The field value to validate.
664
+ * @param {string | bigint | Hex} fieldValue - The field value to validate.
665
+ * @param {Object} input - Additional context for validation.
666
+ * @param {EventLogs[0]} [input.log] - The event log, if validating an event.
667
+ * @param {readonly (string | bigint)[]} [input.decodedArgs] - The decoded function arguments, if validating a function call.
668
668
  * @returns {Promise<boolean>} - Returns true if the field passes the criteria, false otherwise.
669
669
  */
670
670
  public validateFieldAgainstCriteria(
@@ -115,7 +115,7 @@ export class SimpleAllowList extends DeployableTargetWithRBAC<
115
115
  *
116
116
  * @public
117
117
  * @async
118
- * @param {?ReadParams<typeof simpleAllowListAbi, 'owner'>} [params]
118
+ * @param {?ReadParams} [params]
119
119
  * @returns {Promise<Address>} - The address of the owner
120
120
  */
121
121
  public async owner(
@@ -136,7 +136,7 @@ export class SimpleAllowList extends DeployableTargetWithRBAC<
136
136
  * @public
137
137
  * @async
138
138
  * @param {Address} address - The address of the user
139
- * @param {?ReadParams<typeof simpleAllowListAbi, 'setAllowed'>} [params]
139
+ * @param {?ReadParams} [params]
140
140
  * @returns {Promise<boolean>} - True if the user is authorized
141
141
  */
142
142
  public async isAllowed(
@@ -160,7 +160,7 @@ export class SimpleAllowList extends DeployableTargetWithRBAC<
160
160
  * @async
161
161
  * @param {Address[]} addresses - The list of users to update
162
162
  * @param {boolean[]} allowed - The allowed status of each user
163
- * @param {?ReadParams<typeof simpleAllowListAbi, 'setAllowed'>} [params]
163
+ * @param {?ReadParams} [params]
164
164
  * @returns {Promise<void>}
165
165
  */
166
166
  public async setAllowed(
@@ -181,8 +181,8 @@ export class SimpleAllowList extends DeployableTargetWithRBAC<
181
181
  * @async
182
182
  * @param {Address[]} addresses - The list of users to update
183
183
  * @param {boolean[]} allowed - The allowed status of each user
184
- * @param {?ReadParams<typeof simpleAllowListAbi, 'setAllowed'>} [params]
185
- * @returns {Promise<void>}
184
+ * @param {?ReadParams} [params]
185
+ * @returns {Promise<{ hash: `0x${string}`; result: void; }>}
186
186
  */
187
187
  public async setAllowedRaw(
188
188
  addresses: Address[],
@@ -107,7 +107,7 @@ export class SimpleDenyList<
107
107
  *
108
108
  * @public
109
109
  * @async
110
- * @param {?ReadParams<typeof simpleDenyListAbi, 'owner'>} [params]
110
+ * @param {?ReadParams} [params]
111
111
  * @returns {Promise<Address>} - The address of the owner
112
112
  */
113
113
  public async owner(
@@ -128,7 +128,7 @@ export class SimpleDenyList<
128
128
  * @public
129
129
  * @async
130
130
  * @param {Address} address - The address of the user
131
- * @param {?ReadParams<typeof simpleDenyListAbi, 'isAllowed'>} [params]
131
+ * @param {?ReadParams} [params]
132
132
  * @returns {Promise<boolean>} - True if the user is authorized
133
133
  */
134
134
  public async isAllowed(
@@ -151,8 +151,8 @@ export class SimpleDenyList<
151
151
  * @async
152
152
  * @param {Address[]} addresses - The list of users to update
153
153
  * @param {boolean[]} allowed - The denied status of each user
154
- * @param {?WriteParams<typeof simpleDenyListAbi, 'setDenied'>} [params]
155
- * @returns {unknown}
154
+ * @param {?WriteParams} [params]
155
+ * @returns {Promise<void>}
156
156
  */
157
157
  public async setDenied(
158
158
  addresses: Address[],
@@ -171,8 +171,8 @@ export class SimpleDenyList<
171
171
  * @async
172
172
  * @param {Address[]} addresses - The list of users to update
173
173
  * @param {boolean[]} allowed - The denied status of each user
174
- * @param {?WriteParams<typeof simpleDenyListAbi, 'setDenied'>} [params]
175
- * @returns {unknown}
174
+ * @param {?WriteParams} [params]
175
+ * @returns {Promise<{ hash: `0x${string}`; result: void; }>}
176
176
  */
177
177
  public async setDeniedRaw(
178
178
  addresses: Address[],
package/src/Boost.ts CHANGED
@@ -12,6 +12,25 @@ import type { Budget } from './Budgets/Budget';
12
12
  import type { Incentive } from './Incentives/Incentive';
13
13
  import type { Validator } from './Validators/Validator';
14
14
 
15
+ /**
16
+ * Interface representing a `BoostLib.Boost` on-chain struct
17
+ *
18
+ * @export
19
+ * @interface BoostPayload
20
+ * @typedef {BoostPayload}
21
+ */
22
+ export interface RawBoost {
23
+ action: Address;
24
+ validator: Address;
25
+ allowList: Address;
26
+ budget: Address;
27
+ incentives: readonly Address[];
28
+ protocolFee: bigint;
29
+ referralFee: bigint;
30
+ maxParticipants: bigint;
31
+ owner: Address;
32
+ }
33
+
15
34
  /**
16
35
  * Configuration used to instantiate a `Boost` instance.
17
36
  *
@@ -1,11 +1,12 @@
1
1
  import { loadFixture } from '@nomicfoundation/hardhat-toolbox-viem/network-helpers';
2
- import { parseEther, zeroAddress } from 'viem';
2
+ import { pad, parseEther, zeroAddress } from 'viem';
3
3
  import { beforeAll, beforeEach, describe, expect, test, vi } from 'vitest';
4
4
  import {
5
5
  type BudgetFixtures,
6
6
  type Fixtures,
7
7
  defaultOptions,
8
8
  deployFixtures,
9
+ freshBoost,
9
10
  fundBudget,
10
11
  makeMockEventActionPayload,
11
12
  } from '@boostxyz/test/helpers';
@@ -14,6 +15,8 @@ import type { ERC20Incentive } from './Incentives/ERC20Incentive';
14
15
  import { StrategyType } from './claiming';
15
16
  import { IncentiveNotCloneableError } from './errors';
16
17
  import { bytes4 } from './utils';
18
+ import { BOOST_CORE_CLAIM_FEE } from './BoostCore';
19
+ import { accounts } from '@boostxyz/test/accounts';
17
20
 
18
21
  let fixtures: Fixtures, budgets: BudgetFixtures;
19
22
 
@@ -708,4 +711,117 @@ describe('BoostCore', () => {
708
711
  );
709
712
  expect(await core.isAuthorized(zeroAddress)).toBe(true);
710
713
  });
714
+
715
+ test('uses the provided validator when one is specified', async () => {
716
+ const { core } = fixtures;
717
+ const { budget, erc20 } = budgets;
718
+ const customValidator = core.SignerValidator({
719
+ signers: [budget.assertValidAddress()],
720
+ validatorCaller: core.assertValidAddress(),
721
+ });
722
+ const boost = await core.createBoost({
723
+ maxParticipants: 100n,
724
+ budget: budget,
725
+ action: core.EventAction(
726
+ makeMockEventActionPayload(
727
+ core.assertValidAddress(),
728
+ erc20.assertValidAddress(),
729
+ ),
730
+ ),
731
+ validator: customValidator,
732
+ allowList: core.SimpleAllowList({
733
+ owner: defaultOptions.account.address,
734
+ allowed: [defaultOptions.account.address],
735
+ }),
736
+ incentives: [
737
+ core.ERC20Incentive({
738
+ asset: erc20.assertValidAddress(),
739
+ reward: parseEther('1'),
740
+ limit: 100n,
741
+ strategy: StrategyType.POOL,
742
+ }),
743
+ ],
744
+ });
745
+
746
+ expect(boost.validator).toBe(customValidator);
747
+ const signers = await boost.validator.signers(budget.assertValidAddress());
748
+ expect(signers).toBe(true);
749
+ });
750
+
751
+ test('creates a boost with a default validator when none is provided', async () => {
752
+ const { core } = fixtures;
753
+ const { budget, erc20 } = budgets;
754
+ const boost = await core.createBoost({
755
+ maxParticipants: 100n,
756
+ budget: budget,
757
+ action: core.EventAction(
758
+ makeMockEventActionPayload(
759
+ core.assertValidAddress(),
760
+ erc20.assertValidAddress(),
761
+ ),
762
+ ),
763
+ allowList: core.OpenAllowList(),
764
+ incentives: [
765
+ core.ERC20Incentive({
766
+ asset: erc20.assertValidAddress(),
767
+ reward: parseEther('1'),
768
+ limit: 100n,
769
+ strategy: StrategyType.POOL,
770
+ }),
771
+ ],
772
+ });
773
+
774
+ const validator = boost.validator;
775
+
776
+ // expect boostCore to be a validatorCaller
777
+ expect(validator.payload?.validatorCaller).toBe(core.assertValidAddress());
778
+
779
+ // expect current account to be a signer
780
+ const signer = await validator.signers(defaultOptions.account.address);
781
+ expect(signer).toBeDefined();
782
+ expect(signer).toBe(true);
783
+ });
784
+
785
+ test('can retrieve the BoostClaimed event from a transaction hash', async () => {
786
+ // biome-ignore lint/style/noNonNullAssertion: we know this is defined
787
+ const referrer = accounts.at(1)!.account!,
788
+ // biome-ignore lint/style/noNonNullAssertion: we know this is defined
789
+ trustedSigner = accounts.at(0)!;
790
+ const erc20Incentive = fixtures.core.ERC20Incentive({
791
+ asset: budgets.erc20.assertValidAddress(),
792
+ strategy: StrategyType.POOL,
793
+ reward: 1n,
794
+ limit: 1n,
795
+ });
796
+ const boost = await freshBoost(fixtures, {
797
+ budget: budgets.budget,
798
+ incentives: [erc20Incentive],
799
+ });
800
+
801
+ const claimant = trustedSigner.account;
802
+ const incentiveData = pad('0xdef456232173821931823712381232131391321934');
803
+ const incentiveQuantity = 1;
804
+ const claimDataPayload = await boost.validator.encodeClaimData({
805
+ signer: trustedSigner,
806
+ incentiveData,
807
+ chainId: defaultOptions.config.chains[0].id,
808
+ incentiveQuantity,
809
+ claimant,
810
+ boostId: boost.id,
811
+ });
812
+
813
+ const {hash} = await fixtures.core.claimIncentiveRaw(
814
+ boost.id,
815
+ 0n,
816
+ referrer,
817
+ claimDataPayload,
818
+ { value: BOOST_CORE_CLAIM_FEE },
819
+ );
820
+
821
+ const claimInfo = await fixtures.core.getClaimFromTransaction({ hash })
822
+ expect(claimInfo).toBeDefined()
823
+ expect(claimInfo?.claimant).toBe(claimant)
824
+ expect(typeof claimInfo?.boostId).toBe('bigint')
825
+ expect(claimInfo?.referrer).toBe(referrer)
826
+ });
711
827
  });