@boostxyz/sdk 0.0.0-alpha.9 → 1.1.0-alpha.22

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 (257) 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 +7 -7
  4. package/dist/Actions/ContractAction.d.ts +11 -11
  5. package/dist/Actions/ContractAction.d.ts.map +1 -1
  6. package/dist/Actions/ERC721MintAction.d.ts +14 -14
  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 +171 -41
  11. package/dist/Actions/EventAction.d.ts.map +1 -1
  12. package/dist/Actions/EventAction.js +15 -392
  13. package/dist/Actions/EventAction.js.map +1 -1
  14. package/dist/AllowLists/AllowList.cjs +1 -1
  15. package/dist/AllowLists/AllowList.cjs.map +1 -1
  16. package/dist/AllowLists/AllowList.d.ts +6 -4
  17. package/dist/AllowLists/AllowList.d.ts.map +1 -1
  18. package/dist/AllowLists/AllowList.js +45 -23
  19. package/dist/AllowLists/AllowList.js.map +1 -1
  20. package/dist/AllowLists/OpenAllowList.d.ts +423 -0
  21. package/dist/AllowLists/OpenAllowList.d.ts.map +1 -0
  22. package/dist/AllowLists/SimpleAllowList.cjs +1 -1
  23. package/dist/AllowLists/SimpleAllowList.cjs.map +1 -1
  24. package/dist/AllowLists/SimpleAllowList.d.ts +92 -37
  25. package/dist/AllowLists/SimpleAllowList.d.ts.map +1 -1
  26. package/dist/AllowLists/SimpleAllowList.js +55 -71
  27. package/dist/AllowLists/SimpleAllowList.js.map +1 -1
  28. package/dist/AllowLists/SimpleDenyList.cjs +1 -1
  29. package/dist/AllowLists/SimpleDenyList.cjs.map +1 -1
  30. package/dist/AllowLists/SimpleDenyList.d.ts +203 -11
  31. package/dist/AllowLists/SimpleDenyList.d.ts.map +1 -1
  32. package/dist/AllowLists/SimpleDenyList.js +11 -112
  33. package/dist/AllowLists/SimpleDenyList.js.map +1 -1
  34. package/dist/Auth/PassthroughAuth.cjs +1 -1
  35. package/dist/Auth/PassthroughAuth.js +1 -1
  36. package/dist/Boost.cjs +1 -1
  37. package/dist/Boost.cjs.map +1 -1
  38. package/dist/Boost.d.ts +20 -21
  39. package/dist/Boost.d.ts.map +1 -1
  40. package/dist/Boost.js +43 -57
  41. package/dist/Boost.js.map +1 -1
  42. package/dist/BoostCore-BVZExPPu.js +1462 -0
  43. package/dist/BoostCore-BVZExPPu.js.map +1 -0
  44. package/dist/BoostCore-D-E-cnGI.cjs +3 -0
  45. package/dist/BoostCore-D-E-cnGI.cjs.map +1 -0
  46. package/dist/BoostCore.cjs +1 -2
  47. package/dist/BoostCore.cjs.map +1 -1
  48. package/dist/BoostCore.d.ts +748 -77
  49. package/dist/BoostCore.d.ts.map +1 -1
  50. package/dist/BoostCore.js +29 -1150
  51. package/dist/BoostCore.js.map +1 -1
  52. package/dist/BoostRegistry.cjs +1 -1
  53. package/dist/BoostRegistry.cjs.map +1 -1
  54. package/dist/BoostRegistry.d.ts +80 -25
  55. package/dist/BoostRegistry.d.ts.map +1 -1
  56. package/dist/BoostRegistry.js +165 -83
  57. package/dist/BoostRegistry.js.map +1 -1
  58. package/dist/Budgets/Budget.cjs +1 -1
  59. package/dist/Budgets/Budget.cjs.map +1 -1
  60. package/dist/Budgets/Budget.d.ts.map +1 -1
  61. package/dist/Budgets/Budget.js +2 -2
  62. package/dist/Budgets/Budget.js.map +1 -1
  63. package/dist/Budgets/ManagedBudget.cjs +1 -1
  64. package/dist/Budgets/ManagedBudget.cjs.map +1 -1
  65. package/dist/Budgets/ManagedBudget.d.ts +75 -193
  66. package/dist/Budgets/ManagedBudget.d.ts.map +1 -1
  67. package/dist/Budgets/ManagedBudget.js +80 -298
  68. package/dist/Budgets/ManagedBudget.js.map +1 -1
  69. package/dist/Budgets/VestingBudget.d.ts +223 -89
  70. package/dist/Budgets/VestingBudget.d.ts.map +1 -1
  71. package/dist/Deployable/Contract.cjs +1 -1
  72. package/dist/Deployable/Contract.cjs.map +1 -1
  73. package/dist/Deployable/Contract.d.ts +4 -5
  74. package/dist/Deployable/Contract.d.ts.map +1 -1
  75. package/dist/Deployable/Contract.js +5 -7
  76. package/dist/Deployable/Contract.js.map +1 -1
  77. package/dist/Deployable/Deployable.cjs.map +1 -1
  78. package/dist/Deployable/Deployable.d.ts +1 -1
  79. package/dist/Deployable/Deployable.d.ts.map +1 -1
  80. package/dist/Deployable/Deployable.js +3 -5
  81. package/dist/Deployable/Deployable.js.map +1 -1
  82. package/dist/Deployable/DeployableTarget.cjs +1 -1
  83. package/dist/Deployable/DeployableTarget.cjs.map +1 -1
  84. package/dist/Deployable/DeployableTarget.d.ts +13 -13
  85. package/dist/Deployable/DeployableTarget.d.ts.map +1 -1
  86. package/dist/Deployable/DeployableTarget.js +28 -25
  87. package/dist/Deployable/DeployableTarget.js.map +1 -1
  88. package/dist/Deployable/DeployableTargetWithRBAC.cjs +2 -0
  89. package/dist/Deployable/DeployableTargetWithRBAC.cjs.map +1 -0
  90. package/dist/Deployable/DeployableTargetWithRBAC.d.ts +179 -0
  91. package/dist/Deployable/DeployableTargetWithRBAC.d.ts.map +1 -0
  92. package/dist/Deployable/DeployableTargetWithRBAC.js +222 -0
  93. package/dist/Deployable/DeployableTargetWithRBAC.js.map +1 -0
  94. package/dist/EventAction-BZt5cjbe.cjs +2 -0
  95. package/dist/EventAction-BZt5cjbe.cjs.map +1 -0
  96. package/dist/EventAction-C_-hJXWm.js +1541 -0
  97. package/dist/EventAction-C_-hJXWm.js.map +1 -0
  98. package/dist/Incentive-BhHaK3PZ.cjs +2 -0
  99. package/dist/Incentive-BhHaK3PZ.cjs.map +1 -0
  100. package/dist/Incentive-Cqg1w6wD.js +312 -0
  101. package/dist/Incentive-Cqg1w6wD.js.map +1 -0
  102. package/dist/Incentives/AllowListIncentive.cjs +1 -1
  103. package/dist/Incentives/AllowListIncentive.cjs.map +1 -1
  104. package/dist/Incentives/AllowListIncentive.d.ts +38 -16
  105. package/dist/Incentives/AllowListIncentive.d.ts.map +1 -1
  106. package/dist/Incentives/AllowListIncentive.js +42 -29
  107. package/dist/Incentives/AllowListIncentive.js.map +1 -1
  108. package/dist/Incentives/CGDAIncentive.cjs +1 -1
  109. package/dist/Incentives/CGDAIncentive.cjs.map +1 -1
  110. package/dist/Incentives/CGDAIncentive.d.ts +234 -21
  111. package/dist/Incentives/CGDAIncentive.d.ts.map +1 -1
  112. package/dist/Incentives/CGDAIncentive.js +45 -32
  113. package/dist/Incentives/CGDAIncentive.js.map +1 -1
  114. package/dist/Incentives/ERC1155Incentive.d.ts +224 -37
  115. package/dist/Incentives/ERC1155Incentive.d.ts.map +1 -1
  116. package/dist/Incentives/ERC20Incentive.cjs +1 -1
  117. package/dist/Incentives/ERC20Incentive.cjs.map +1 -1
  118. package/dist/Incentives/ERC20Incentive.d.ts +230 -29
  119. package/dist/Incentives/ERC20Incentive.d.ts.map +1 -1
  120. package/dist/Incentives/ERC20Incentive.js +56 -43
  121. package/dist/Incentives/ERC20Incentive.js.map +1 -1
  122. package/dist/{Budgets/SimpleBudget.d.ts → Incentives/ERC20VariableCriteriaIncentive.d.ts} +335 -440
  123. package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts.map +1 -0
  124. package/dist/Incentives/ERC20VariableIncentive.d.ts +231 -29
  125. package/dist/Incentives/ERC20VariableIncentive.d.ts.map +1 -1
  126. package/dist/Incentives/Incentive.cjs +1 -1
  127. package/dist/Incentives/Incentive.cjs.map +1 -1
  128. package/dist/Incentives/Incentive.d.ts +4 -4
  129. package/dist/Incentives/Incentive.d.ts.map +1 -1
  130. package/dist/Incentives/Incentive.js +16 -296
  131. package/dist/Incentives/Incentive.js.map +1 -1
  132. package/dist/Incentives/PointsIncentive.cjs +1 -1
  133. package/dist/Incentives/PointsIncentive.cjs.map +1 -1
  134. package/dist/Incentives/PointsIncentive.d.ts +40 -18
  135. package/dist/Incentives/PointsIncentive.d.ts.map +1 -1
  136. package/dist/Incentives/PointsIncentive.js +37 -24
  137. package/dist/Incentives/PointsIncentive.js.map +1 -1
  138. package/dist/SimpleDenyList-BUR17Tt1.cjs +2 -0
  139. package/dist/SimpleDenyList-BUR17Tt1.cjs.map +1 -0
  140. package/dist/SimpleDenyList-CGaWjuld.js +132 -0
  141. package/dist/SimpleDenyList-CGaWjuld.js.map +1 -0
  142. package/dist/Validators/SignerValidator.cjs +1 -1
  143. package/dist/Validators/SignerValidator.cjs.map +1 -1
  144. package/dist/Validators/SignerValidator.d.ts +16 -16
  145. package/dist/Validators/SignerValidator.d.ts.map +1 -1
  146. package/dist/Validators/SignerValidator.js +30 -27
  147. package/dist/Validators/SignerValidator.js.map +1 -1
  148. package/dist/Validators/Validator.cjs +1 -1
  149. package/dist/Validators/Validator.cjs.map +1 -1
  150. package/dist/Validators/Validator.d.ts +1 -1
  151. package/dist/Validators/Validator.js +2 -2
  152. package/dist/Validators/Validator.js.map +1 -1
  153. package/dist/claiming.cjs.map +1 -1
  154. package/dist/claiming.d.ts +1 -1
  155. package/dist/claiming.js.map +1 -1
  156. package/dist/componentInterfaces-BBCFkrZv.js +14 -0
  157. package/dist/componentInterfaces-BBCFkrZv.js.map +1 -0
  158. package/dist/componentInterfaces-DRI_dQ-P.cjs +2 -0
  159. package/dist/componentInterfaces-DRI_dQ-P.cjs.map +1 -0
  160. package/dist/deployments-DVXioW2i.cjs +2 -0
  161. package/dist/deployments-DVXioW2i.cjs.map +1 -0
  162. package/dist/deployments-oykLv3_Z.js +43 -0
  163. package/dist/deployments-oykLv3_Z.js.map +1 -0
  164. package/dist/deployments.json +44 -0
  165. package/dist/errors.cjs +1 -1
  166. package/dist/errors.cjs.map +1 -1
  167. package/dist/errors.d.ts +256 -20
  168. package/dist/errors.d.ts.map +1 -1
  169. package/dist/errors.js +183 -26
  170. package/dist/errors.js.map +1 -1
  171. package/dist/{generated-57_Kffpz.js → generated-CKt2yCQd.js} +3613 -1869
  172. package/dist/generated-CKt2yCQd.js.map +1 -0
  173. package/dist/generated-CyTNlOwM.cjs +3 -0
  174. package/dist/generated-CyTNlOwM.cjs.map +1 -0
  175. package/dist/index.cjs +1 -1
  176. package/dist/index.d.ts +5 -0
  177. package/dist/index.d.ts.map +1 -1
  178. package/dist/index.js +142 -108
  179. package/dist/index.js.map +1 -1
  180. package/dist/transfers.cjs.map +1 -1
  181. package/dist/transfers.d.ts +1 -1
  182. package/dist/transfers.js.map +1 -1
  183. package/dist/utils.cjs +1 -1
  184. package/dist/utils.cjs.map +1 -1
  185. package/dist/utils.d.ts +26 -12
  186. package/dist/utils.d.ts.map +1 -1
  187. package/dist/utils.js +38 -23
  188. package/dist/utils.js.map +1 -1
  189. package/package.json +20 -10
  190. package/src/Actions/Action.test.ts +14 -13
  191. package/src/Actions/ContractAction.test.ts +10 -10
  192. package/src/Actions/ContractAction.ts +11 -12
  193. package/src/Actions/ERC721MintAction.test.ts +6 -6
  194. package/src/Actions/ERC721MintAction.ts +14 -15
  195. package/src/Actions/EventAction.test.ts +729 -109
  196. package/src/Actions/EventAction.ts +542 -84
  197. package/src/AllowLists/AllowList.test.ts +7 -7
  198. package/src/AllowLists/AllowList.ts +5 -3
  199. package/src/AllowLists/OpenAllowList.test.ts +40 -0
  200. package/src/AllowLists/OpenAllowList.ts +45 -0
  201. package/src/AllowLists/SimpleAllowList.test.ts +4 -4
  202. package/src/AllowLists/SimpleAllowList.ts +39 -61
  203. package/src/AllowLists/SimpleDenyList.test.ts +4 -4
  204. package/src/AllowLists/SimpleDenyList.ts +40 -17
  205. package/src/Auth/PassthroughAuth.test.ts +1 -1
  206. package/src/Boost.ts +21 -24
  207. package/src/BoostCore.test.ts +323 -268
  208. package/src/BoostCore.ts +396 -219
  209. package/src/BoostRegistry.test.ts +53 -0
  210. package/src/BoostRegistry.ts +161 -40
  211. package/src/Budgets/Budget.test.ts +2 -2
  212. package/src/Budgets/Budget.ts +1 -2
  213. package/src/Budgets/ManagedBudget.test.ts +82 -19
  214. package/src/Budgets/ManagedBudget.ts +48 -310
  215. package/src/Budgets/VestingBudget.test.ts +7 -7
  216. package/src/Budgets/VestingBudget.ts +34 -106
  217. package/src/Deployable/Contract.ts +4 -5
  218. package/src/Deployable/Deployable.ts +1 -1
  219. package/src/Deployable/DeployableTarget.ts +30 -19
  220. package/src/Deployable/DeployableTargetWithRBAC.ts +323 -0
  221. package/src/Incentives/AllowListIncentive.test.ts +5 -5
  222. package/src/Incentives/AllowListIncentive.ts +29 -15
  223. package/src/Incentives/CGDAIncentive.test.ts +9 -6
  224. package/src/Incentives/CGDAIncentive.ts +38 -18
  225. package/src/Incentives/ERC1155Incentive.test.ts +3 -3
  226. package/src/Incentives/ERC1155Incentive.ts +28 -29
  227. package/src/Incentives/ERC20Incentive.test.ts +9 -6
  228. package/src/Incentives/ERC20Incentive.ts +46 -26
  229. package/src/Incentives/ERC20VariableCriteriaIncentive.test.ts +184 -0
  230. package/src/Incentives/ERC20VariableCriteriaIncentive.ts +324 -0
  231. package/src/Incentives/ERC20VariableIncentive.test.ts +8 -11
  232. package/src/Incentives/ERC20VariableIncentive.ts +49 -26
  233. package/src/Incentives/Incentive.test.ts +4 -1
  234. package/src/Incentives/Incentive.ts +7 -6
  235. package/src/Incentives/PointsIncentive.test.ts +24 -25
  236. package/src/Incentives/PointsIncentive.ts +31 -17
  237. package/src/Validators/SignerValidator.test.ts +6 -6
  238. package/src/Validators/SignerValidator.ts +19 -17
  239. package/src/Validators/Validator.test.ts +2 -2
  240. package/src/Validators/Validator.ts +1 -1
  241. package/src/claiming.ts +1 -1
  242. package/src/errors.ts +345 -21
  243. package/src/index.test.ts +118 -36
  244. package/src/index.ts +5 -0
  245. package/src/transfers.ts +1 -1
  246. package/src/utils.test.ts +2 -2
  247. package/src/utils.ts +61 -12
  248. package/dist/Budgets/SimpleBudget.d.ts.map +0 -1
  249. package/dist/componentInterfaces-CKCBwG16.cjs +0 -2
  250. package/dist/componentInterfaces-CKCBwG16.cjs.map +0 -1
  251. package/dist/componentInterfaces-DYkaxBda.js +0 -13
  252. package/dist/componentInterfaces-DYkaxBda.js.map +0 -1
  253. package/dist/generated-57_Kffpz.js.map +0 -1
  254. package/dist/generated-wKBNvm48.cjs +0 -3
  255. package/dist/generated-wKBNvm48.cjs.map +0 -1
  256. package/src/Budgets/SimpleBudget.test.ts +0 -152
  257. package/src/Budgets/SimpleBudget.ts +0 -564
@@ -1,27 +1,53 @@
1
- import { selectors as eventSelectors } from '@boostxyz/signatures/events';
2
- import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
3
- import { type Hex, type Log, isAddress } from 'viem';
1
+ import { selectors as eventSelectors } from "@boostxyz/signatures/events";
2
+ import { selectors as funcSelectors } from "@boostxyz/signatures/functions";
3
+ import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
4
+ import {
5
+ type AbiEvent,
6
+ type Address,
7
+ type GetLogsReturnType,
8
+ type Hex,
9
+ type Log,
10
+ isAddress,
11
+ pad,
12
+ parseEther,
13
+ toHex,
14
+ zeroAddress,
15
+ zeroHash,
16
+ } from 'viem';
4
17
  import { beforeAll, beforeEach, describe, expect, test } from 'vitest';
5
- import type { MockERC721 } from '../../test/MockERC721';
6
- import { accounts } from '../../test/accounts';
18
+ import type { MockERC20 } from '@boostxyz/test/MockERC20';
19
+ import type { MockERC721 } from '@boostxyz/test/MockERC721';
20
+ import { accounts } from '@boostxyz/test/accounts';
7
21
  import {
8
22
  type Fixtures,
23
+ type StringEmitterFixtures,
9
24
  defaultOptions,
10
25
  deployFixtures,
26
+ fundErc20,
27
+ deployStringEmitterMock,
11
28
  fundErc721,
12
- } from '../../test/helpers';
29
+ } from '@boostxyz/test/helpers';
13
30
  import {
14
31
  EventAction,
32
+ type EventLogs,
15
33
  type EventActionPayloadSimple,
16
34
  FilterType,
17
35
  PrimitiveType,
18
36
  SignatureType,
19
- } from './EventAction';
37
+ Criteria,
38
+ anyActionParameter,
39
+ } from "./EventAction";
20
40
 
21
- let fixtures: Fixtures, erc721: MockERC721;
41
+ let fixtures: Fixtures,
42
+ erc721: MockERC721,
43
+ erc20: MockERC20,
44
+ stringEmitterFixtures: StringEmitterFixtures;
45
+ let chainId: number;
22
46
 
23
47
  beforeAll(async () => {
24
- fixtures = await loadFixture(deployFixtures);
48
+ fixtures = await loadFixture(deployFixtures(defaultOptions));
49
+ stringEmitterFixtures = await loadFixture(deployStringEmitterMock);
50
+ chainId = defaultOptions.config.chains[0].id;
25
51
  });
26
52
 
27
53
  function basicErc721TransferAction(
@@ -30,21 +56,25 @@ function basicErc721TransferAction(
30
56
  return {
31
57
  actionClaimant: {
32
58
  signatureType: SignatureType.EVENT,
33
- signature: eventSelectors['Transfer(address,address,uint256)'] as Hex,
34
- fieldIndex: 2,
59
+ signature: eventSelectors[
60
+ "Transfer(address indexed,address indexed,uint256 indexed)"
61
+ ] as Hex,
62
+ fieldIndex: 1,
35
63
  targetContract: erc721.assertValidAddress(),
36
- chainid: defaultOptions.config.chains[0].id,
64
+ chainid: chainId,
37
65
  },
38
66
  actionSteps: [
39
67
  {
40
- signature: eventSelectors['Transfer(address,address,uint256)'] as Hex,
68
+ signature: eventSelectors[
69
+ "Transfer(address indexed,address indexed,uint256 indexed)"
70
+ ] as Hex,
41
71
  signatureType: SignatureType.EVENT,
42
72
  targetContract: erc721.assertValidAddress(),
43
- chainid: defaultOptions.config.chains[0].id,
73
+ chainid: chainId,
44
74
  actionParameter: {
45
75
  filterType: FilterType.EQUAL,
46
76
  fieldType: PrimitiveType.ADDRESS,
47
- fieldIndex: 2,
77
+ fieldIndex: 1,
48
78
  filterData: accounts[1].account,
49
79
  },
50
80
  },
@@ -52,157 +82,747 @@ function basicErc721TransferAction(
52
82
  };
53
83
  }
54
84
 
55
- /*
85
+ function basicErc721TransferActionWithEmptyActionParameter(erc721: MockERC721) {
86
+ const eventActionPayload = basicErc721TransferAction(erc721)
87
+ if (eventActionPayload.actionSteps[0]?.actionParameter) {
88
+ eventActionPayload.actionSteps[0].actionParameter = anyActionParameter()
89
+ }
90
+ return eventActionPayload
91
+ }
92
+
93
+ function cloneEventAction(fixtures: Fixtures, erc721: MockERC721, eventActionPayload = basicErc721TransferAction(erc721)) {
94
+ return function cloneEventAction() {
95
+ return fixtures.registry.initialize(
96
+ crypto.randomUUID(),
97
+ fixtures.core.EventAction(eventActionPayload),
98
+ );
99
+ };
100
+ }
101
+
56
102
  function basicErc721MintFuncAction(
57
103
  erc721: MockERC721,
58
104
  ): EventActionPayloadSimple {
59
105
  return {
60
106
  actionClaimant: {
61
107
  signatureType: SignatureType.FUNC,
62
- signature: funcSelectors['mint(address)'] as Hex,
108
+ signature: funcSelectors["mint(address)"] as Hex,
63
109
  fieldIndex: 0,
64
110
  targetContract: erc721.assertValidAddress(),
111
+ chainid: chainId,
65
112
  },
66
113
  actionSteps: [
67
114
  {
68
- signature: funcSelectors['mint(address)'] as Hex,
115
+ signature: funcSelectors["mint(address)"] as Hex,
69
116
  signatureType: SignatureType.FUNC,
70
117
  actionType: 0,
71
118
  targetContract: erc721.assertValidAddress(),
119
+ chainid: chainId,
72
120
  actionParameter: {
73
121
  filterType: FilterType.EQUAL,
74
122
  fieldType: PrimitiveType.ADDRESS,
75
- fieldIndex: 2,
123
+ fieldIndex: 0,
76
124
  filterData: accounts[1].account,
77
125
  },
78
126
  },
79
127
  ],
80
128
  };
81
129
  }
82
- */
83
130
 
84
- function cloneEventAction(fixtures: Fixtures, erc721: MockERC721) {
85
- return function cloneEventAction() {
131
+ function basicErc721MintFuncActionWithEmptyActionParameter(erc721: MockERC721) {
132
+ const eventActionPayload = basicErc721MintFuncAction(erc721)
133
+ if (eventActionPayload.actionSteps[0]?.actionParameter) {
134
+ eventActionPayload.actionSteps[0].actionParameter = anyActionParameter()
135
+ }
136
+ return eventActionPayload
137
+ }
138
+
139
+ function basicErc20MintFuncAction(erc20: MockERC20): EventActionPayloadSimple {
140
+ return {
141
+ actionClaimant: {
142
+ signatureType: SignatureType.FUNC,
143
+ signature: funcSelectors["mint(address to, uint256 amount)"] as Hex,
144
+ fieldIndex: 0,
145
+ targetContract: erc20.assertValidAddress(),
146
+ chainid: chainId,
147
+ },
148
+ actionSteps: [
149
+ {
150
+ signature: funcSelectors["mint(address to, uint256 amount)"] as Hex,
151
+ signatureType: SignatureType.FUNC,
152
+ actionType: 0,
153
+ targetContract: erc20.assertValidAddress(),
154
+ chainid: chainId,
155
+ actionParameter: {
156
+ filterType: FilterType.EQUAL,
157
+ fieldType: PrimitiveType.ADDRESS,
158
+ fieldIndex: 0,
159
+ filterData: accounts[1].account,
160
+ },
161
+ },
162
+ ],
163
+ };
164
+ }
165
+
166
+ function indexedStringErc721TransferAction(
167
+ filterType: FilterType,
168
+ data: Hex,
169
+ stringEmitterAddress: Address,
170
+ erc721: MockERC721,
171
+ ): EventActionPayloadSimple {
172
+ return {
173
+ actionClaimant: {
174
+ signatureType: SignatureType.EVENT,
175
+ signature: eventSelectors[
176
+ "Transfer(address indexed,address indexed,uint256 indexed)"
177
+ ] as Hex,
178
+ fieldIndex: 1,
179
+ targetContract: erc721.assertValidAddress(),
180
+ chainid: chainId,
181
+ },
182
+ actionSteps: [
183
+ {
184
+ signature: eventSelectors[
185
+ "InfoIndexed(address indexed,string indexed)"
186
+ ] as Hex,
187
+ signatureType: SignatureType.EVENT,
188
+ actionType: 0,
189
+ targetContract: stringEmitterAddress,
190
+ chainid: chainId,
191
+ actionParameter: {
192
+ filterType,
193
+ fieldType: PrimitiveType.STRING,
194
+ fieldIndex: 1,
195
+ filterData: data,
196
+ },
197
+ },
198
+ ],
199
+ };
200
+ }
201
+
202
+ function stringErc721TransferAction(
203
+ filterType: FilterType,
204
+ data: Hex,
205
+ stringEmitterAddress: Address,
206
+ erc721: MockERC721,
207
+ ): EventActionPayloadSimple {
208
+ return {
209
+ actionClaimant: {
210
+ signatureType: SignatureType.EVENT,
211
+ signature: eventSelectors[
212
+ "Transfer(address indexed,address indexed,uint256 indexed)"
213
+ ] as Hex,
214
+ fieldIndex: 1,
215
+ targetContract: erc721.assertValidAddress(),
216
+ chainid: chainId,
217
+ },
218
+ actionSteps: [
219
+ {
220
+ signature: eventSelectors["Info(address,string)"] as Hex,
221
+ signatureType: SignatureType.EVENT,
222
+ actionType: 0,
223
+ targetContract: stringEmitterAddress,
224
+ chainid: chainId,
225
+ actionParameter: {
226
+ filterType,
227
+ fieldType: PrimitiveType.STRING,
228
+ fieldIndex: 1,
229
+ filterData: data,
230
+ },
231
+ },
232
+ ],
233
+ };
234
+ }
235
+
236
+ function cloneFunctionAction20(fixtures: Fixtures, erc20: MockERC20) {
237
+ return function cloneFunctionAction20() {
86
238
  return fixtures.registry.clone(
87
239
  crypto.randomUUID(),
88
240
  new fixtures.bases.EventAction(
89
241
  defaultOptions,
90
- basicErc721TransferAction(erc721),
242
+ basicErc20MintFuncAction(erc20),
91
243
  ),
92
244
  );
93
245
  };
94
246
  }
95
247
 
96
- describe('EventAction', () => {
248
+ function cloneFunctionAction(fixtures: Fixtures, erc721: MockERC721, eventActionPayload = basicErc721MintFuncAction(erc721)) {
249
+ return function cloneFunctionAction() {
250
+ return fixtures.registry.clone(
251
+ crypto.randomUUID(),
252
+ new fixtures.bases.EventAction(
253
+ defaultOptions,
254
+ eventActionPayload
255
+ ),
256
+ );
257
+ };
258
+ }
259
+
260
+ function cloneStringEventAction(
261
+ fixtures: Fixtures,
262
+ actionParams: EventActionPayloadSimple,
263
+ ) {
264
+ return function loadFixtureCallback() {
265
+ return fixtures.registry.clone(
266
+ crypto.randomUUID(),
267
+ new fixtures.bases.EventAction(defaultOptions, actionParams),
268
+ );
269
+ };
270
+ }
271
+
272
+ function createMockCriteria(
273
+ filterType: FilterType,
274
+ fieldType: PrimitiveType,
275
+ filterData: Hex,
276
+ fieldIndex: number = 0
277
+ ): Criteria {
278
+ return {
279
+ filterType,
280
+ fieldType,
281
+ filterData,
282
+ fieldIndex,
283
+ };
284
+ }
285
+
286
+ describe("EventAction Event Selector", () => {
97
287
  beforeEach(async () => {
98
288
  erc721 = await loadFixture(fundErc721(defaultOptions));
99
289
  });
100
290
 
101
- test('can successfully be deployed', async () => {
291
+ describe("basic transfer event", () => {
292
+ test("can successfully be deployed", async () => {
293
+ const action = new EventAction(
294
+ defaultOptions,
295
+ basicErc721TransferAction(erc721),
296
+ );
297
+ await action.deploy();
298
+ expect(isAddress(action.assertValidAddress())).toBe(true);
299
+ });
300
+
301
+ test("can get an action step", async () => {
302
+ const action = await loadFixture(cloneEventAction(fixtures, erc721));
303
+ const step = await action.getActionStep(0);
304
+ if (!step)
305
+ throw new Error("there should be an action step at this index");
306
+ step.targetContract = step.targetContract.toUpperCase() as Hex;
307
+ step.actionParameter.filterData =
308
+ step.actionParameter.filterData.toUpperCase() as Hex;
309
+ expect(step).toMatchObject({
310
+ signature: eventSelectors[
311
+ "Transfer(address indexed,address indexed,uint256 indexed)"
312
+ ] as Hex,
313
+ signatureType: SignatureType.EVENT,
314
+ actionType: 0,
315
+ targetContract: erc721.assertValidAddress().toUpperCase(),
316
+ actionParameter: {
317
+ filterType: FilterType.EQUAL,
318
+ fieldType: PrimitiveType.ADDRESS,
319
+ fieldIndex: 1,
320
+ filterData: accounts[1].account.toUpperCase(),
321
+ },
322
+ });
323
+ });
324
+
325
+ test("can get all action steps", async () => {
326
+ const action = await loadFixture(cloneEventAction(fixtures, erc721));
327
+ const steps = await action.getActionSteps();
328
+ expect(steps.length).toBe(1);
329
+ const step = steps[0]!;
330
+ step.targetContract = step.targetContract.toUpperCase() as Hex;
331
+ step.actionParameter.filterData =
332
+ step.actionParameter.filterData.toUpperCase() as Hex;
333
+ expect(step).toMatchObject({
334
+ signature: eventSelectors[
335
+ "Transfer(address indexed,address indexed,uint256 indexed)"
336
+ ] as Hex,
337
+ signatureType: SignatureType.EVENT,
338
+ actionType: 0,
339
+ targetContract: erc721.assertValidAddress().toUpperCase(),
340
+ actionParameter: {
341
+ filterType: FilterType.EQUAL,
342
+ fieldType: PrimitiveType.ADDRESS,
343
+ fieldIndex: 1,
344
+ filterData: accounts[1].account.toUpperCase(),
345
+ },
346
+ });
347
+ });
348
+
349
+ test("can get the total number of action steps", async () => {
350
+ const action = await loadFixture(cloneEventAction(fixtures, erc721));
351
+ const count = await action.getActionStepsCount();
352
+ expect(count).toBe(1);
353
+ });
354
+
355
+ test("can get the action claimant", async () => {
356
+ const action = await loadFixture(cloneEventAction(fixtures, erc721));
357
+ const claimant = await action.getActionClaimant();
358
+ claimant.targetContract = claimant.targetContract.toUpperCase() as Hex;
359
+ expect(claimant).toMatchObject({
360
+ signatureType: SignatureType.EVENT,
361
+ signature: eventSelectors[
362
+ "Transfer(address indexed,address indexed,uint256 indexed)"
363
+ ] as Hex,
364
+ fieldIndex: 1,
365
+ });
366
+ });
367
+
368
+ test("can get all action steps", async () => {
369
+ const action = await loadFixture(cloneEventAction(fixtures, erc721));
370
+ const steps = await action.getActionSteps();
371
+ expect(steps.length).toBe(1);
372
+ const step = steps[0]!;
373
+ step.targetContract = step.targetContract.toUpperCase() as Hex;
374
+ step.actionParameter.filterData =
375
+ step.actionParameter.filterData.toUpperCase() as Hex;
376
+ expect(step).toMatchObject({
377
+ signature: eventSelectors[
378
+ "Transfer(address indexed,address indexed,uint256 indexed)"
379
+ ] as Hex,
380
+ signatureType: SignatureType.EVENT,
381
+ actionType: 0,
382
+ targetContract: erc721.assertValidAddress().toUpperCase(),
383
+ actionParameter: {
384
+ filterType: FilterType.EQUAL,
385
+ fieldType: PrimitiveType.ADDRESS,
386
+ fieldIndex: 1,
387
+ filterData: accounts[1].account.toUpperCase(),
388
+ },
389
+ });
390
+ });
391
+
392
+ test("can get the total number of action steps", async () => {
393
+ const action = await loadFixture(cloneEventAction(fixtures, erc721));
394
+ const count = await action.getActionStepsCount();
395
+ expect(count).toBe(1);
396
+ });
397
+
398
+ test("can get the action claimant", async () => {
399
+ const action = await loadFixture(cloneEventAction(fixtures, erc721));
400
+ const claimant = await action.getActionClaimant();
401
+ claimant.targetContract = claimant.targetContract.toUpperCase() as Hex;
402
+ expect(claimant).toMatchObject({
403
+ signatureType: SignatureType.EVENT,
404
+ signature: eventSelectors[
405
+ "Transfer(address indexed,address indexed,uint256 indexed)"
406
+ ] as Hex,
407
+ fieldIndex: 1,
408
+ targetContract: erc721.assertValidAddress().toUpperCase(),
409
+ });
410
+ });
411
+
412
+ test("with a correct log, validates", async () => {
413
+ const action = await loadFixture(cloneEventAction(fixtures, erc721));
414
+ const recipient = accounts[1].account;
415
+ await erc721.approve(recipient, 1n);
416
+ const { hash } = await erc721.transferFromRaw(defaultOptions.account.address, recipient, 1n);
417
+ expect(await action.validateActionSteps({ hash, chainId })).toBe(true);
418
+ });
419
+
420
+ test("can supply your own logs to validate against", async () => {
421
+ const hash = "0xff0e6ab0c4961ec14b7b40afec83ed7d7a77582683512a262e641d21f82efea5"
422
+ const logs: EventLogs = [
423
+ {
424
+ eventName: "Transfer",
425
+ args: [
426
+ "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
427
+ "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
428
+ 1n,
429
+ ],
430
+ address: erc721.assertValidAddress(),
431
+ blockHash:
432
+ "0xbf602f988260519805d032be46d6ff97fbefbee6924b21097074d6d0bc34eced",
433
+ blockNumber: 1203n,
434
+ data: "0x",
435
+ logIndex: 0,
436
+ removed: false,
437
+ topics: [
438
+ "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
439
+ "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266",
440
+ "0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8",
441
+ "0x0000000000000000000000000000000000000000000000000000000000000001",
442
+ ],
443
+ transactionHash:
444
+ "0xff0e6ab0c4961ec14b7b40afec83ed7d7a77582683512a262e641d21f82efea5",
445
+ transactionIndex: 0,
446
+ },
447
+ ];
448
+ const action = await loadFixture(cloneEventAction(fixtures, erc721));
449
+ expect(await action.validateActionSteps({ hash, chainId, logs })).toBe(true);
450
+ });
451
+
452
+ describe("string event actions", () => {
453
+ test("cannot parse and validate contains for an emitted string event with an indexed param", async () => {
454
+ const action = await loadFixture(
455
+ cloneStringEventAction(
456
+ fixtures,
457
+ indexedStringErc721TransferAction(
458
+ FilterType.CONTAINS,
459
+ toHex("ello"),
460
+ stringEmitterFixtures.address,
461
+ erc721,
462
+ ),
463
+ ),
464
+ );
465
+
466
+ const hash = await stringEmitterFixtures.emitIndexedString("Hello world");
467
+ await expect(() => action.validateActionSteps({ hash, chainId })).rejects.toThrowError(
468
+ /Parameter is not transparently stored onchain/,
469
+ );
470
+ });
471
+ test("can parse and validate contains for an emitted string event", async () => {
472
+ const action = await loadFixture(
473
+ cloneStringEventAction(
474
+ fixtures,
475
+ stringErc721TransferAction(
476
+ FilterType.CONTAINS,
477
+ toHex("ello"),
478
+ stringEmitterFixtures.address,
479
+ erc721,
480
+ ),
481
+ ),
482
+ );
483
+ const hash = await stringEmitterFixtures.emitString("Hello world");
484
+ expect(await action.validateActionSteps({ hash, chainId })).toBe(true);
485
+ });
486
+ test("can parse and validate regex for an emitted string event", async () => {
487
+ const action = await loadFixture(
488
+ cloneStringEventAction(
489
+ fixtures,
490
+ stringErc721TransferAction(
491
+ FilterType.REGEX,
492
+ toHex("[hH]ello"),
493
+ stringEmitterFixtures.address,
494
+ erc721,
495
+ ),
496
+ ),
497
+ );
498
+
499
+ const hash = await stringEmitterFixtures.emitString("Hello world");
500
+ expect(await action.validateActionSteps({ hash, chainId })).toBe(true);
501
+ });
502
+ });
503
+
504
+ test("can derive the claimant from an event action", async () => {
505
+ const action = await loadFixture(cloneEventAction(fixtures, erc721));
506
+ const recipient = accounts[1].account;
507
+ await erc721.approve(recipient, 1n);
508
+ const { hash } = await erc721.transferFromRaw(defaultOptions.account.address, recipient, 1n);
509
+ expect(
510
+ await action.deriveActionClaimantFromTransaction(await action.getActionClaimant(), {
511
+ hash,
512
+ chainId,
513
+ }),
514
+ ).toBe(recipient);
515
+ });
516
+
517
+ test("can derive the claimant from a function action", async () => {
518
+ const action = await loadFixture(cloneFunctionAction(fixtures, erc721));
519
+ const recipient = accounts[1].account;
520
+ const { hash } = await erc721.mintRaw(recipient, {
521
+ value: parseEther(".1"),
522
+ });
523
+
524
+ expect(
525
+ await action.deriveActionClaimantFromTransaction(await action.getActionClaimant(), {
526
+ hash,
527
+ chainId,
528
+ }),
529
+ ).toBe(recipient);
530
+ });
531
+
532
+ test('validates empty actionParameter', async () => {
533
+ const action = await loadFixture(cloneEventAction(fixtures, erc721, basicErc721TransferActionWithEmptyActionParameter(erc721)))
534
+ const recipient = accounts[1].account;
535
+ await erc721.approve(recipient, 1n);
536
+ const { hash } = await erc721.transferFromRaw(defaultOptions.account.address, recipient, 1n);
537
+ expect(await action.validateActionSteps({ hash, chainId })).toBe(true);
538
+ })
539
+ });
540
+ });
541
+
542
+ describe("validateFieldAgainstCriteria unit tests", () => {
543
+ let action: EventAction
544
+ beforeAll(async () => {
545
+ action = await loadFixture(cloneEventAction(fixtures, erc721));
546
+ });
547
+ const mockAddress = '0x1234567890abcdef1234567890abcdef12345678';
548
+ const mockInput = { decodedArgs: ['not used'] };
549
+
550
+ test('should return true for EQUAL filter type with ADDRESS field type', () => {
551
+ const mockCriteria = createMockCriteria(FilterType.EQUAL, PrimitiveType.ADDRESS, mockAddress);
552
+ const result = action.validateFieldAgainstCriteria(mockCriteria, mockAddress, mockInput);
553
+ expect(result).toBe(true);
554
+ });
555
+
556
+ test('should return true for EQUAL filter type with UINT field type', () => {
557
+ const mockCriteria = createMockCriteria(FilterType.EQUAL, PrimitiveType.UINT, '0xc8');
558
+ const result = action.validateFieldAgainstCriteria(mockCriteria, 200n, mockInput);
559
+ expect(result).toBe(true);
560
+ });
561
+ test('should return true for EQUAL filter type with STRING field type when values match', () => {
562
+ // Decoded value: 'hello'
563
+ const mockCriteria = createMockCriteria(FilterType.EQUAL, PrimitiveType.STRING, '0x68656c6c6f');
564
+ const result = action.validateFieldAgainstCriteria(mockCriteria, 'hello', mockInput);
565
+ expect(result).toBe(true);
566
+ });
567
+
568
+ test('should return false for EQUAL filter type with STRING field type when values do not match', () => {
569
+ // Decoded value: 'hello'
570
+ const mockCriteria = createMockCriteria(FilterType.EQUAL, PrimitiveType.STRING, '0x68656c6c6f');
571
+ const result = action.validateFieldAgainstCriteria(mockCriteria, 'world', mockInput);
572
+ expect(result).toBe(false);
573
+ });
574
+
575
+ test('should return true for EQUAL filter type with BYTES field type when values match', () => {
576
+ // Decoded value: '0x68656c6c6f' (hex for 'hello')
577
+ const mockCriteria = createMockCriteria(FilterType.EQUAL, PrimitiveType.BYTES, '0x68656c6c6f');
578
+ const result = action.validateFieldAgainstCriteria(mockCriteria, '0x68656c6c6f', mockInput);
579
+ expect(result).toBe(true);
580
+ });
581
+
582
+ test('should return false for EQUAL filter type with BYTES field type when values do not match', () => {
583
+ // Decoded value: '0x68656c6c6f' (hex for 'hello')
584
+ const mockCriteria = createMockCriteria(FilterType.EQUAL, PrimitiveType.BYTES, '0x68656c6c6f');
585
+ const result = action.validateFieldAgainstCriteria(mockCriteria, '0x776f726c64', mockInput); // hex for 'world'
586
+ expect(result).toBe(false);
587
+ });
588
+
589
+ test('should return false for NOT_EQUAL filter type with ADDRESS field type', () => {
590
+ const mockCriteria = createMockCriteria(FilterType.NOT_EQUAL, PrimitiveType.ADDRESS, mockAddress);
591
+ const result = action.validateFieldAgainstCriteria(mockCriteria, zeroAddress, mockInput);
592
+ expect(result).toBe(true);
593
+ });
594
+
595
+ test('should return true for NOT_EQUAL filter type with UINT field type', () => {
596
+ const mockCriteria = createMockCriteria(FilterType.NOT_EQUAL, PrimitiveType.UINT, '0xc9');
597
+ const result = action.validateFieldAgainstCriteria(mockCriteria, 200n, mockInput);
598
+ expect(result).toBe(true);
599
+ });
600
+
601
+ test('should throw InvalidNumericalCriteriaError for GREATER_THAN filter type with non-uint field type', () => {
602
+ const mockCriteria = createMockCriteria(FilterType.GREATER_THAN, PrimitiveType.STRING, '0x100');
603
+ expect(() => action.validateFieldAgainstCriteria(mockCriteria, '200', mockInput)).toThrow('non-numerical criteria');
604
+ });
605
+
606
+ test('should return true for GREATER_THAN filter type with UINT field type', () => {
607
+ const mockCriteria = createMockCriteria(FilterType.GREATER_THAN, PrimitiveType.UINT, '0x64');
608
+ const result = action.validateFieldAgainstCriteria(mockCriteria, 200n, mockInput);
609
+ expect(result).toBe(true);
610
+ });
611
+
612
+ test('should return true for CONTAINS filter type with STRING field type', () => {
613
+ // Decoded value: 'hello'
614
+ const mockCriteria = createMockCriteria(FilterType.CONTAINS, PrimitiveType.STRING, '0x68656c6c6f');
615
+ const result = action.validateFieldAgainstCriteria(mockCriteria, 'hello world', mockInput);
616
+ expect(result).toBe(true);
617
+ });
618
+
619
+ test('should return true for CONTAINS filter type with BYTES field type', () => {
620
+ const mockCriteria = createMockCriteria(FilterType.CONTAINS, PrimitiveType.BYTES, '0xbeef');
621
+ const result = action.validateFieldAgainstCriteria(mockCriteria, '0xdeadbeef', mockInput);
622
+ expect(result).toBe(true);
623
+ });
624
+
625
+ test('should throw FieldValueNotComparableError for CONTAINS filter type with non-string/bytes field type', () => {
626
+ // Decoded value: 123
627
+ const mockCriteria = createMockCriteria(FilterType.CONTAINS, PrimitiveType.UINT, '0x7b');
628
+ expect(() => action.validateFieldAgainstCriteria(mockCriteria, 123n, mockInput)).toThrow(/only .* bytes or string/);
629
+ });
630
+
631
+ test('should throw UnrecognizedFilterTypeError for unrecognized filter type', () => {
632
+ const mockCriteria = createMockCriteria(6 as FilterType, PrimitiveType.STRING, '0x74657374'); // Decoded value: 'test'
633
+ expect(() => action.validateFieldAgainstCriteria(mockCriteria, 'test', mockInput)).toThrow('Invalid FilterType');
634
+ });
635
+
636
+ test('should return true for LESS_THAN filter type with UINT field type', () => {
637
+ // Decoded value: 200
638
+ const mockCriteria = createMockCriteria(FilterType.LESS_THAN, PrimitiveType.UINT, '0xc8');
639
+ const result = action.validateFieldAgainstCriteria(mockCriteria, 100n, mockInput);
640
+ expect(result).toBe(true);
641
+ });
642
+
643
+ test('should return false for LESS_THAN filter type with UINT field type when value is greater', () => {
644
+ // Decoded value: 100
645
+ const mockCriteria = createMockCriteria(FilterType.LESS_THAN, PrimitiveType.UINT, '0x64');
646
+ const result = action.validateFieldAgainstCriteria(mockCriteria, 200n, mockInput);
647
+ expect(result).toBe(false);
648
+ });
649
+
650
+ test('should throw InvalidNumericalCriteriaError for LESS_THAN filter type with non-uint field type', () => {
651
+ // Decoded value: 100
652
+ const mockCriteria = createMockCriteria(FilterType.LESS_THAN, PrimitiveType.STRING, '0x64');
653
+ expect(() => action.validateFieldAgainstCriteria(mockCriteria, '50', mockInput)).toThrow('non-numerical');
654
+ });
655
+
656
+ test('should throw InvalidNumericalCriteriaError for LESS_THAN filter type with ADDRESS field type', () => {
657
+ const mockCriteria = createMockCriteria(FilterType.LESS_THAN, PrimitiveType.ADDRESS, '0x1234567890abcdef1234567890abcdef12345678');
658
+ expect(() => action.validateFieldAgainstCriteria(mockCriteria, '0x1234567890abcdef1234567890abcdef12345678', mockInput)).toThrow('non-numerical');
659
+ });
660
+
661
+ test('should return true for anyActionParameter', async () => {
662
+ const mockCriteria = anyActionParameter()
663
+ const result = action.validateFieldAgainstCriteria(mockCriteria, zeroHash, mockInput)
664
+ expect(result).toBe(true)
665
+ })
666
+ })
667
+
668
+ describe("EventAction Func Selector", () => {
669
+ beforeEach(async () => {
670
+ erc721 = await loadFixture(fundErc721(defaultOptions));
671
+ erc20 = await loadFixture(fundErc20(defaultOptions));
672
+ });
673
+
674
+ test("can be deployed successfully", async () => {
102
675
  const action = new EventAction(
103
676
  defaultOptions,
104
- basicErc721TransferAction(erc721),
677
+ basicErc721MintFuncAction(erc721),
105
678
  );
106
679
  await action.deploy();
107
680
  expect(isAddress(action.assertValidAddress())).toBe(true);
108
681
  });
109
682
 
110
- test('can get an action step', async () => {
111
- const action = await loadFixture(cloneEventAction(fixtures, erc721));
112
- const step = await action.getActionStep(0);
113
- if (!step) throw new Error('there should be an action step at this index');
114
- step.targetContract = step.targetContract.toUpperCase() as Hex;
115
- step.actionParameter.filterData =
116
- step.actionParameter.filterData.toUpperCase() as Hex;
117
- expect(step).toMatchObject({
118
- signature: eventSelectors['Transfer(address,address,uint256)'] as Hex,
119
- signatureType: SignatureType.EVENT,
120
- actionType: 0,
121
- targetContract: erc721.assertValidAddress().toUpperCase(),
122
- actionParameter: {
123
- filterType: FilterType.EQUAL,
124
- fieldType: PrimitiveType.ADDRESS,
125
- fieldIndex: 2,
126
- filterData: accounts[1].account.toUpperCase(),
127
- },
683
+ test("validates function action step with correct hash", async () => {
684
+ const action = await loadFixture(cloneFunctionAction(fixtures, erc721));
685
+ const actionSteps = await action.getActionSteps();
686
+ const actionStep = actionSteps[0]!
687
+ const recipient = accounts[1].account;
688
+ const { hash } = await erc721.mintRaw(recipient, {
689
+ value: parseEther(".1"),
128
690
  });
691
+
692
+ expect(
693
+ await action.isActionStepValid(actionStep, { hash, chainId })
694
+ ).toBe(true);
129
695
  });
130
696
 
131
- test('can get all action steps', async () => {
132
- const action = await loadFixture(cloneEventAction(fixtures, erc721));
133
- const steps = await action.getActionSteps();
134
- expect(steps.length).toBe(1);
135
- const step = steps[0]!;
136
- step.targetContract = step.targetContract.toUpperCase() as Hex;
137
- step.actionParameter.filterData =
138
- step.actionParameter.filterData.toUpperCase() as Hex;
139
- expect(step).toMatchObject({
140
- signature: eventSelectors['Transfer(address,address,uint256)'] as Hex,
141
- signatureType: SignatureType.EVENT,
142
- actionType: 0,
143
- targetContract: erc721.assertValidAddress().toUpperCase(),
144
- actionParameter: {
145
- filterType: FilterType.EQUAL,
146
- fieldType: PrimitiveType.ADDRESS,
147
- fieldIndex: 2,
148
- filterData: accounts[1].account.toUpperCase(),
149
- },
697
+ test("validates function step with EQUAL filter", async () => {
698
+ const action = await loadFixture(cloneFunctionAction(fixtures, erc721));
699
+ const actionSteps = await action.getActionSteps();
700
+ const actionStep = actionSteps[0]!
701
+ const recipient = accounts[1].account;
702
+ const { hash } = await erc721.mintRaw(recipient, {
703
+ value: parseEther(".1"),
150
704
  });
705
+
706
+ const criteriaMatch = await action.isActionStepValid(actionStep, {
707
+ hash,
708
+ chainId,
709
+ });
710
+
711
+ expect(criteriaMatch).toBe(true);
151
712
  });
152
713
 
153
- test('can get the total number of action steps', async () => {
154
- const action = await loadFixture(cloneEventAction(fixtures, erc721));
155
- const count = await action.getActionStepsCount();
156
- expect(count).toBe(1);
714
+ test("fails validation with incorrect function signature", async () => {
715
+ const action = await loadFixture(cloneFunctionAction(fixtures, erc721));
716
+ const actionSteps = await action.getActionSteps();
717
+ const actionStep = actionSteps[0]!;
718
+ const recipient = accounts[1].account;
719
+
720
+ const invalidStep = {
721
+ ...actionStep,
722
+ signature: funcSelectors["mint(address to, uint256 amount)"] as Hex, // Intentional mismatch
723
+ };
724
+
725
+ const { hash } = await erc721.mintRaw(recipient, {
726
+ value: parseEther(".1"),
727
+ });
728
+
729
+ try {
730
+ await action.isActionStepValid(invalidStep, { hash, chainId });
731
+ } catch (e) {
732
+ expect(e).toBeInstanceOf(Error);
733
+ expect((e as Error).message).toContain(
734
+ 'Failed to decode function data: Encoded function signature "0x6a627842"',
735
+ );
736
+ }
157
737
  });
158
738
 
159
- test('can get the action claimant', async () => {
160
- const action = await loadFixture(cloneEventAction(fixtures, erc721));
161
- const claimant = await action.getActionClaimant();
162
- claimant.targetContract = claimant.targetContract.toUpperCase() as Hex;
163
- expect(claimant).toMatchObject({
164
- signatureType: SignatureType.EVENT,
165
- signature: eventSelectors['Transfer(address,address,uint256)'] as Hex,
166
- fieldIndex: 2,
167
- targetContract: erc721.assertValidAddress().toUpperCase(),
739
+ test('validates empty actionParameter', async () => {
740
+ const action = await loadFixture(cloneFunctionAction(fixtures, erc721, basicErc721MintFuncActionWithEmptyActionParameter(erc721)))
741
+ const recipient = accounts[1].account;
742
+ const { hash } = await erc721.mintRaw(recipient, {
743
+ value: parseEther(".1"),
168
744
  });
745
+
746
+ expect(await action.validateActionSteps({ hash, chainId })).toBe(true);
747
+ })
748
+
749
+ test("validates against NOT_EQUAL filter criteria", async () => {
750
+ const action = await loadFixture(cloneFunctionAction(fixtures, erc721));
751
+ const actionSteps = await action.getActionSteps();
752
+ const actionStep = actionSteps[0]!;
753
+ actionStep.actionParameter.filterType = FilterType.NOT_EQUAL;
754
+ const recipient = accounts[2].account;
755
+ const { hash } = await erc721.mintRaw(recipient, {
756
+ value: parseEther(".1"),
757
+ });
758
+
759
+ expect(
760
+ await action.isActionStepValid(actionStep, {
761
+ hash,
762
+ chainId,
763
+ }),
764
+ ).toBe(true);
169
765
  });
170
766
 
171
- test('with no logs, does not validate', async () => {
172
- const action = await loadFixture(cloneEventAction(fixtures, erc721));
173
- expect(await action.validateActionSteps()).toBe(false);
767
+ test("validates GREATER_THAN criteria for numeric values", async () => {
768
+ const action = await loadFixture(cloneFunctionAction20(fixtures, erc20));
769
+ const actionSteps = await action.getActionSteps();
770
+ const actionStep = actionSteps[0]!;
771
+
772
+ actionStep.actionParameter = {
773
+ filterType: FilterType.GREATER_THAN,
774
+ fieldType: PrimitiveType.UINT,
775
+ fieldIndex: 1,
776
+ filterData: toHex("1"),
777
+ };
778
+
779
+ const address = accounts[1].account;
780
+ const value = 400n;
781
+ const { hash } = await erc20.mintRaw(address, value);
782
+
783
+ expect(
784
+ await action.isActionStepValid(actionStep, {
785
+ hash,
786
+ chainId,
787
+ }),
788
+ ).toBe(true);
174
789
  });
175
790
 
176
- test('with a correct log, validates', async () => {
177
- const action = await loadFixture(cloneEventAction(fixtures, erc721));
791
+ test("validates LESS_THAN criteria for numeric values", async () => {
792
+ const action = await loadFixture(cloneFunctionAction20(fixtures, erc20));
793
+ const actionSteps = await action.getActionSteps();
794
+ const actionStep = actionSteps[0]!;
795
+ actionStep.actionParameter = {
796
+ filterType: FilterType.LESS_THAN,
797
+ fieldType: PrimitiveType.UINT,
798
+ fieldIndex: 1,
799
+ filterData: toHex("5"),
800
+ };
801
+
802
+ const address = accounts[1].account;
803
+ const value = 4n;
804
+ const { hash } = await erc20.mintRaw(address, value);
805
+
806
+ expect(
807
+ await action.isActionStepValid(actionStep, {
808
+ hash,
809
+ chainId,
810
+ }),
811
+ ).toBe(true);
812
+ });
813
+
814
+ test("validates entire flow of function action", async () => {
815
+ const action = await loadFixture(cloneFunctionAction(fixtures, erc721));
178
816
  const recipient = accounts[1].account;
179
- await erc721.approve(recipient, 1n);
180
- await erc721.transferFrom(defaultOptions.account.address, recipient, 1n);
181
- expect(await action.validateActionSteps()).toBe(true);
182
- });
183
-
184
- test('can supply your own logs to validate against', async () => {
185
- const log = {
186
- eventName: 'Transfer',
187
- args: undefined,
188
- address: erc721.assertValidAddress(),
189
- blockHash:
190
- '0xbf602f988260519805d032be46d6ff97fbefbee6924b21097074d6d0bc34eced',
191
- blockNumber: 1203n,
192
- data: '0x',
193
- logIndex: 0,
194
- removed: false,
195
- topics: [
196
- '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
197
- '0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266',
198
- '0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8',
199
- '0x0000000000000000000000000000000000000000000000000000000000000001',
200
- ],
201
- transactionHash:
202
- '0xff0e6ab0c4961ec14b7b40afec83ed7d7a77582683512a262e641d21f82efea5',
203
- transactionIndex: 0,
204
- } as Log;
205
- const action = await loadFixture(cloneEventAction(fixtures, erc721));
206
- expect(await action.validateActionSteps({ logs: [log] })).toBe(true);
817
+ const { hash } = await erc721.mintRaw(recipient, {
818
+ value: parseEther(".1"),
819
+ });
820
+
821
+ expect(
822
+ await action.validateActionSteps({
823
+ hash,
824
+ chainId,
825
+ }),
826
+ ).toBe(true);
207
827
  });
208
828
  });