@boostxyz/sdk 0.0.0-alpha.8 → 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 (266) 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 +57 -14
  5. package/dist/Actions/ContractAction.d.ts.map +1 -1
  6. package/dist/Actions/ERC721MintAction.d.ts +50 -23
  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 +420 -45
  11. package/dist/Actions/EventAction.d.ts.map +1 -1
  12. package/dist/Actions/EventAction.js +15 -225
  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 +123 -39
  25. package/dist/AllowLists/SimpleAllowList.d.ts.map +1 -1
  26. package/dist/AllowLists/SimpleAllowList.js +75 -76
  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 +234 -13
  31. package/dist/AllowLists/SimpleDenyList.d.ts.map +1 -1
  32. package/dist/AllowLists/SimpleDenyList.js +11 -200
  33. package/dist/AllowLists/SimpleDenyList.js.map +1 -1
  34. package/dist/Auth/PassthroughAuth.cjs +1 -1
  35. package/dist/Auth/PassthroughAuth.cjs.map +1 -1
  36. package/dist/Auth/PassthroughAuth.js +4 -4
  37. package/dist/Auth/PassthroughAuth.js.map +1 -1
  38. package/dist/Boost.cjs +1 -1
  39. package/dist/Boost.cjs.map +1 -1
  40. package/dist/Boost.d.ts +105 -14
  41. package/dist/Boost.d.ts.map +1 -1
  42. package/dist/Boost.js +137 -5
  43. package/dist/Boost.js.map +1 -1
  44. package/dist/BoostCore-BVZExPPu.js +1462 -0
  45. package/dist/BoostCore-BVZExPPu.js.map +1 -0
  46. package/dist/BoostCore-D-E-cnGI.cjs +3 -0
  47. package/dist/BoostCore-D-E-cnGI.cjs.map +1 -0
  48. package/dist/BoostCore.cjs +1 -2
  49. package/dist/BoostCore.cjs.map +1 -1
  50. package/dist/BoostCore.d.ts +759 -82
  51. package/dist/BoostCore.d.ts.map +1 -1
  52. package/dist/BoostCore.js +29 -1148
  53. package/dist/BoostCore.js.map +1 -1
  54. package/dist/BoostRegistry.cjs +1 -1
  55. package/dist/BoostRegistry.cjs.map +1 -1
  56. package/dist/BoostRegistry.d.ts +83 -28
  57. package/dist/BoostRegistry.d.ts.map +1 -1
  58. package/dist/BoostRegistry.js +170 -93
  59. package/dist/BoostRegistry.js.map +1 -1
  60. package/dist/Budgets/Budget.cjs +1 -1
  61. package/dist/Budgets/Budget.cjs.map +1 -1
  62. package/dist/Budgets/Budget.d.ts.map +1 -1
  63. package/dist/Budgets/Budget.js +2 -2
  64. package/dist/Budgets/Budget.js.map +1 -1
  65. package/dist/Budgets/ManagedBudget.cjs +1 -1
  66. package/dist/Budgets/ManagedBudget.cjs.map +1 -1
  67. package/dist/Budgets/ManagedBudget.d.ts +112 -192
  68. package/dist/Budgets/ManagedBudget.d.ts.map +1 -1
  69. package/dist/Budgets/ManagedBudget.js +89 -290
  70. package/dist/Budgets/ManagedBudget.js.map +1 -1
  71. package/dist/Budgets/VestingBudget.d.ts +277 -91
  72. package/dist/Budgets/VestingBudget.d.ts.map +1 -1
  73. package/dist/Deployable/Contract.cjs +1 -1
  74. package/dist/Deployable/Contract.cjs.map +1 -1
  75. package/dist/Deployable/Contract.d.ts +4 -5
  76. package/dist/Deployable/Contract.d.ts.map +1 -1
  77. package/dist/Deployable/Contract.js +6 -8
  78. package/dist/Deployable/Contract.js.map +1 -1
  79. package/dist/Deployable/Deployable.cjs.map +1 -1
  80. package/dist/Deployable/Deployable.d.ts +1 -1
  81. package/dist/Deployable/Deployable.d.ts.map +1 -1
  82. package/dist/Deployable/Deployable.js +3 -5
  83. package/dist/Deployable/Deployable.js.map +1 -1
  84. package/dist/Deployable/DeployableTarget.cjs +1 -1
  85. package/dist/Deployable/DeployableTarget.cjs.map +1 -1
  86. package/dist/Deployable/DeployableTarget.d.ts +13 -13
  87. package/dist/Deployable/DeployableTarget.d.ts.map +1 -1
  88. package/dist/Deployable/DeployableTarget.js +30 -27
  89. package/dist/Deployable/DeployableTarget.js.map +1 -1
  90. package/dist/Deployable/DeployableTargetWithRBAC.cjs +2 -0
  91. package/dist/Deployable/DeployableTargetWithRBAC.cjs.map +1 -0
  92. package/dist/Deployable/DeployableTargetWithRBAC.d.ts +179 -0
  93. package/dist/Deployable/DeployableTargetWithRBAC.d.ts.map +1 -0
  94. package/dist/Deployable/DeployableTargetWithRBAC.js +222 -0
  95. package/dist/Deployable/DeployableTargetWithRBAC.js.map +1 -0
  96. package/dist/EventAction-BZt5cjbe.cjs +2 -0
  97. package/dist/EventAction-BZt5cjbe.cjs.map +1 -0
  98. package/dist/EventAction-C_-hJXWm.js +1541 -0
  99. package/dist/EventAction-C_-hJXWm.js.map +1 -0
  100. package/dist/Incentive-BhHaK3PZ.cjs +2 -0
  101. package/dist/Incentive-BhHaK3PZ.cjs.map +1 -0
  102. package/dist/Incentive-Cqg1w6wD.js +312 -0
  103. package/dist/Incentive-Cqg1w6wD.js.map +1 -0
  104. package/dist/Incentives/AllowListIncentive.cjs +1 -1
  105. package/dist/Incentives/AllowListIncentive.cjs.map +1 -1
  106. package/dist/Incentives/AllowListIncentive.d.ts +73 -21
  107. package/dist/Incentives/AllowListIncentive.d.ts.map +1 -1
  108. package/dist/Incentives/AllowListIncentive.js +61 -36
  109. package/dist/Incentives/AllowListIncentive.js.map +1 -1
  110. package/dist/Incentives/CGDAIncentive.cjs +1 -1
  111. package/dist/Incentives/CGDAIncentive.cjs.map +1 -1
  112. package/dist/Incentives/CGDAIncentive.d.ts +323 -26
  113. package/dist/Incentives/CGDAIncentive.d.ts.map +1 -1
  114. package/dist/Incentives/CGDAIncentive.js +73 -39
  115. package/dist/Incentives/CGDAIncentive.js.map +1 -1
  116. package/dist/Incentives/ERC1155Incentive.d.ts +291 -43
  117. package/dist/Incentives/ERC1155Incentive.d.ts.map +1 -1
  118. package/dist/Incentives/ERC20Incentive.cjs +1 -1
  119. package/dist/Incentives/ERC20Incentive.cjs.map +1 -1
  120. package/dist/Incentives/ERC20Incentive.d.ts +278 -33
  121. package/dist/Incentives/ERC20Incentive.d.ts.map +1 -1
  122. package/dist/Incentives/ERC20Incentive.js +79 -47
  123. package/dist/Incentives/ERC20Incentive.js.map +1 -1
  124. package/dist/{Budgets/SimpleBudget.d.ts → Incentives/ERC20VariableCriteriaIncentive.d.ts} +346 -420
  125. package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts.map +1 -0
  126. package/dist/Incentives/ERC20VariableIncentive.d.ts +271 -32
  127. package/dist/Incentives/ERC20VariableIncentive.d.ts.map +1 -1
  128. package/dist/Incentives/Incentive.cjs +1 -1
  129. package/dist/Incentives/Incentive.cjs.map +1 -1
  130. package/dist/Incentives/Incentive.d.ts +4 -4
  131. package/dist/Incentives/Incentive.d.ts.map +1 -1
  132. package/dist/Incentives/Incentive.js +16 -280
  133. package/dist/Incentives/Incentive.js.map +1 -1
  134. package/dist/Incentives/PointsIncentive.cjs +1 -1
  135. package/dist/Incentives/PointsIncentive.cjs.map +1 -1
  136. package/dist/Incentives/PointsIncentive.d.ts +89 -23
  137. package/dist/Incentives/PointsIncentive.d.ts.map +1 -1
  138. package/dist/Incentives/PointsIncentive.js +66 -36
  139. package/dist/Incentives/PointsIncentive.js.map +1 -1
  140. package/dist/SimpleDenyList-BUR17Tt1.cjs +2 -0
  141. package/dist/SimpleDenyList-BUR17Tt1.cjs.map +1 -0
  142. package/dist/SimpleDenyList-CGaWjuld.js +132 -0
  143. package/dist/SimpleDenyList-CGaWjuld.js.map +1 -0
  144. package/dist/Validators/SignerValidator.cjs +1 -1
  145. package/dist/Validators/SignerValidator.cjs.map +1 -1
  146. package/dist/Validators/SignerValidator.d.ts +310 -17
  147. package/dist/Validators/SignerValidator.d.ts.map +1 -1
  148. package/dist/Validators/SignerValidator.js +164 -36
  149. package/dist/Validators/SignerValidator.js.map +1 -1
  150. package/dist/Validators/Validator.cjs +1 -1
  151. package/dist/Validators/Validator.cjs.map +1 -1
  152. package/dist/Validators/Validator.d.ts +1 -1
  153. package/dist/Validators/Validator.js +2 -2
  154. package/dist/Validators/Validator.js.map +1 -1
  155. package/dist/claiming.cjs +2 -0
  156. package/dist/claiming.cjs.map +1 -0
  157. package/dist/claiming.d.ts +43 -0
  158. package/dist/claiming.d.ts.map +1 -0
  159. package/dist/claiming.js +17 -0
  160. package/dist/claiming.js.map +1 -0
  161. package/dist/componentInterfaces-BBCFkrZv.js +14 -0
  162. package/dist/componentInterfaces-BBCFkrZv.js.map +1 -0
  163. package/dist/componentInterfaces-DRI_dQ-P.cjs +2 -0
  164. package/dist/componentInterfaces-DRI_dQ-P.cjs.map +1 -0
  165. package/dist/deployments-DVXioW2i.cjs +2 -0
  166. package/dist/deployments-DVXioW2i.cjs.map +1 -0
  167. package/dist/deployments-oykLv3_Z.js +43 -0
  168. package/dist/deployments-oykLv3_Z.js.map +1 -0
  169. package/dist/deployments.json +44 -0
  170. package/dist/errors.cjs +1 -1
  171. package/dist/errors.cjs.map +1 -1
  172. package/dist/errors.d.ts +257 -21
  173. package/dist/errors.d.ts.map +1 -1
  174. package/dist/errors.js +183 -26
  175. package/dist/errors.js.map +1 -1
  176. package/dist/{generated-Cbv8zFkf.js → generated-CKt2yCQd.js} +3615 -1868
  177. package/dist/generated-CKt2yCQd.js.map +1 -0
  178. package/dist/generated-CyTNlOwM.cjs +3 -0
  179. package/dist/generated-CyTNlOwM.cjs.map +1 -0
  180. package/dist/index.cjs +1 -1
  181. package/dist/index.d.ts +9 -4
  182. package/dist/index.d.ts.map +1 -1
  183. package/dist/index.js +143 -126
  184. package/dist/index.js.map +1 -1
  185. package/dist/transfers.cjs +2 -0
  186. package/dist/transfers.cjs.map +1 -0
  187. package/dist/transfers.d.ts +198 -0
  188. package/dist/transfers.d.ts.map +1 -0
  189. package/dist/transfers.js +84 -0
  190. package/dist/transfers.js.map +1 -0
  191. package/dist/utils.cjs +1 -1
  192. package/dist/utils.cjs.map +1 -1
  193. package/dist/utils.d.ts +25 -1380
  194. package/dist/utils.d.ts.map +1 -1
  195. package/dist/utils.js +36 -648
  196. package/dist/utils.js.map +1 -1
  197. package/package.json +34 -10
  198. package/src/Actions/Action.test.ts +19 -17
  199. package/src/Actions/ContractAction.test.ts +14 -16
  200. package/src/Actions/ContractAction.ts +84 -22
  201. package/src/Actions/ERC721MintAction.test.ts +8 -8
  202. package/src/Actions/ERC721MintAction.ts +83 -30
  203. package/src/Actions/EventAction.test.ts +759 -113
  204. package/src/Actions/EventAction.ts +991 -116
  205. package/src/AllowLists/AllowList.test.ts +7 -7
  206. package/src/AllowLists/AllowList.ts +5 -3
  207. package/src/AllowLists/OpenAllowList.test.ts +40 -0
  208. package/src/AllowLists/OpenAllowList.ts +45 -0
  209. package/src/AllowLists/SimpleAllowList.test.ts +4 -4
  210. package/src/AllowLists/SimpleAllowList.ts +86 -65
  211. package/src/AllowLists/SimpleDenyList.test.ts +4 -4
  212. package/src/AllowLists/SimpleDenyList.ts +87 -126
  213. package/src/Auth/PassthroughAuth.test.ts +1 -1
  214. package/src/Auth/PassthroughAuth.ts +1 -1
  215. package/src/Boost.ts +147 -15
  216. package/src/BoostCore.test.ts +326 -278
  217. package/src/BoostCore.ts +425 -242
  218. package/src/BoostRegistry.test.ts +53 -0
  219. package/src/BoostRegistry.ts +168 -50
  220. package/src/Budgets/Budget.test.ts +2 -2
  221. package/src/Budgets/Budget.ts +1 -2
  222. package/src/Budgets/ManagedBudget.test.ts +82 -19
  223. package/src/Budgets/ManagedBudget.ts +106 -315
  224. package/src/Budgets/VestingBudget.test.ts +7 -7
  225. package/src/Budgets/VestingBudget.ts +110 -112
  226. package/src/Deployable/Contract.ts +5 -6
  227. package/src/Deployable/Deployable.ts +1 -1
  228. package/src/Deployable/DeployableTarget.ts +32 -21
  229. package/src/Deployable/DeployableTargetWithRBAC.ts +323 -0
  230. package/src/Incentives/AllowListIncentive.test.ts +7 -10
  231. package/src/Incentives/AllowListIncentive.ts +88 -30
  232. package/src/Incentives/CGDAIncentive.test.ts +11 -12
  233. package/src/Incentives/CGDAIncentive.ts +161 -37
  234. package/src/Incentives/ERC1155Incentive.test.ts +5 -16
  235. package/src/Incentives/ERC1155Incentive.ts +132 -51
  236. package/src/Incentives/ERC20Incentive.test.ts +15 -23
  237. package/src/Incentives/ERC20Incentive.ts +131 -46
  238. package/src/Incentives/ERC20VariableCriteriaIncentive.test.ts +184 -0
  239. package/src/Incentives/ERC20VariableCriteriaIncentive.ts +324 -0
  240. package/src/Incentives/ERC20VariableIncentive.test.ts +12 -35
  241. package/src/Incentives/ERC20VariableIncentive.ts +118 -43
  242. package/src/Incentives/Incentive.test.ts +5 -2
  243. package/src/Incentives/Incentive.ts +7 -6
  244. package/src/Incentives/PointsIncentive.test.ts +26 -30
  245. package/src/Incentives/PointsIncentive.ts +110 -34
  246. package/src/Validators/SignerValidator.test.ts +9 -13
  247. package/src/Validators/SignerValidator.ts +437 -26
  248. package/src/Validators/Validator.test.ts +2 -2
  249. package/src/Validators/Validator.ts +1 -1
  250. package/src/claiming.ts +56 -0
  251. package/src/errors.ts +346 -22
  252. package/src/index.test.ts +118 -36
  253. package/src/index.ts +15 -7
  254. package/src/transfers.ts +284 -0
  255. package/src/utils.test.ts +2 -2
  256. package/src/utils.ts +61 -2061
  257. package/dist/Budgets/SimpleBudget.d.ts.map +0 -1
  258. package/dist/componentInterfaces-CKCBwG16.cjs +0 -2
  259. package/dist/componentInterfaces-CKCBwG16.cjs.map +0 -1
  260. package/dist/componentInterfaces-DYkaxBda.js +0 -13
  261. package/dist/componentInterfaces-DYkaxBda.js.map +0 -1
  262. package/dist/generated-BzszviNp.cjs +0 -3
  263. package/dist/generated-BzszviNp.cjs.map +0 -1
  264. package/dist/generated-Cbv8zFkf.js.map +0 -1
  265. package/src/Budgets/SimpleBudget.test.ts +0 -152
  266. package/src/Budgets/SimpleBudget.ts +0 -521
@@ -1,31 +1,53 @@
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";
1
4
  import {
2
- readAActionGetComponentInterface,
3
- readEventActionGetComponentInterface,
4
- } from '@boostxyz/evm';
5
- import { selectors } from '@boostxyz/signatures/events';
6
- import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
7
- import { type Hex, type Log, isAddress } from 'viem';
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';
8
17
  import { beforeAll, beforeEach, describe, expect, test } from 'vitest';
9
- import type { MockERC721 } from '../../test/MockERC721';
10
- 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';
11
21
  import {
12
22
  type Fixtures,
23
+ type StringEmitterFixtures,
13
24
  defaultOptions,
14
25
  deployFixtures,
26
+ fundErc20,
27
+ deployStringEmitterMock,
15
28
  fundErc721,
16
- } from '../../test/helpers';
29
+ } from '@boostxyz/test/helpers';
17
30
  import {
31
+ EventAction,
32
+ type EventLogs,
18
33
  type EventActionPayloadSimple,
19
34
  FilterType,
20
35
  PrimitiveType,
21
36
  SignatureType,
22
- } from '../utils';
23
- import { EventAction } from './EventAction';
37
+ Criteria,
38
+ anyActionParameter,
39
+ } from "./EventAction";
24
40
 
25
- let fixtures: Fixtures, erc721: MockERC721;
41
+ let fixtures: Fixtures,
42
+ erc721: MockERC721,
43
+ erc20: MockERC20,
44
+ stringEmitterFixtures: StringEmitterFixtures;
45
+ let chainId: number;
26
46
 
27
47
  beforeAll(async () => {
28
- fixtures = await loadFixture(deployFixtures);
48
+ fixtures = await loadFixture(deployFixtures(defaultOptions));
49
+ stringEmitterFixtures = await loadFixture(deployStringEmitterMock);
50
+ chainId = defaultOptions.config.chains[0].id;
29
51
  });
30
52
 
31
53
  function basicErc721TransferAction(
@@ -34,149 +56,773 @@ function basicErc721TransferAction(
34
56
  return {
35
57
  actionClaimant: {
36
58
  signatureType: SignatureType.EVENT,
37
- signature: selectors['Transfer(address,address,uint256)'] as Hex,
38
- fieldIndex: 2,
59
+ signature: eventSelectors[
60
+ "Transfer(address indexed,address indexed,uint256 indexed)"
61
+ ] as Hex,
62
+ fieldIndex: 1,
39
63
  targetContract: erc721.assertValidAddress(),
64
+ chainid: chainId,
40
65
  },
41
66
  actionSteps: [
42
67
  {
43
- signature: selectors['Transfer(address,address,uint256)'] as Hex,
68
+ signature: eventSelectors[
69
+ "Transfer(address indexed,address indexed,uint256 indexed)"
70
+ ] as Hex,
44
71
  signatureType: SignatureType.EVENT,
45
- actionType: 0,
46
72
  targetContract: erc721.assertValidAddress(),
73
+ chainid: chainId,
47
74
  actionParameter: {
48
75
  filterType: FilterType.EQUAL,
49
76
  fieldType: PrimitiveType.ADDRESS,
50
- fieldIndex: 2,
51
- filterData: accounts.at(1)!.account,
77
+ fieldIndex: 1,
78
+ filterData: accounts[1].account,
52
79
  },
53
80
  },
54
81
  ],
55
82
  };
56
83
  }
57
84
 
58
- function cloneEventAction(fixtures: Fixtures, erc721: MockERC721) {
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)) {
59
94
  return function cloneEventAction() {
95
+ return fixtures.registry.initialize(
96
+ crypto.randomUUID(),
97
+ fixtures.core.EventAction(eventActionPayload),
98
+ );
99
+ };
100
+ }
101
+
102
+ function basicErc721MintFuncAction(
103
+ erc721: MockERC721,
104
+ ): EventActionPayloadSimple {
105
+ return {
106
+ actionClaimant: {
107
+ signatureType: SignatureType.FUNC,
108
+ signature: funcSelectors["mint(address)"] as Hex,
109
+ fieldIndex: 0,
110
+ targetContract: erc721.assertValidAddress(),
111
+ chainid: chainId,
112
+ },
113
+ actionSteps: [
114
+ {
115
+ signature: funcSelectors["mint(address)"] as Hex,
116
+ signatureType: SignatureType.FUNC,
117
+ actionType: 0,
118
+ targetContract: erc721.assertValidAddress(),
119
+ chainid: chainId,
120
+ actionParameter: {
121
+ filterType: FilterType.EQUAL,
122
+ fieldType: PrimitiveType.ADDRESS,
123
+ fieldIndex: 0,
124
+ filterData: accounts[1].account,
125
+ },
126
+ },
127
+ ],
128
+ };
129
+ }
130
+
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() {
60
238
  return fixtures.registry.clone(
61
239
  crypto.randomUUID(),
62
240
  new fixtures.bases.EventAction(
63
241
  defaultOptions,
64
- basicErc721TransferAction(erc721),
242
+ basicErc20MintFuncAction(erc20),
65
243
  ),
66
244
  );
67
245
  };
68
246
  }
69
247
 
70
- 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", () => {
71
287
  beforeEach(async () => {
72
288
  erc721 = await loadFixture(fundErc721(defaultOptions));
73
289
  });
74
290
 
75
- 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 () => {
76
675
  const action = new EventAction(
77
676
  defaultOptions,
78
- basicErc721TransferAction(erc721),
677
+ basicErc721MintFuncAction(erc721),
79
678
  );
80
679
  await action.deploy();
81
680
  expect(isAddress(action.assertValidAddress())).toBe(true);
82
681
  });
83
682
 
84
- test('can get an action step', async () => {
85
- const action = await loadFixture(cloneEventAction(fixtures, erc721));
86
- const step = await action.getActionStep(0);
87
- if (!step) throw new Error('there should be an action step at this index');
88
- step.targetContract = step.targetContract.toUpperCase() as Hex;
89
- step.actionParameter.filterData =
90
- step.actionParameter.filterData.toUpperCase() as Hex;
91
- expect(step).toMatchObject({
92
- signature: selectors['Transfer(address,address,uint256)'] as Hex,
93
- signatureType: SignatureType.EVENT,
94
- actionType: 0,
95
- targetContract: erc721.assertValidAddress().toUpperCase(),
96
- actionParameter: {
97
- filterType: FilterType.EQUAL,
98
- fieldType: PrimitiveType.ADDRESS,
99
- fieldIndex: 2,
100
- filterData: accounts.at(1)!.account.toUpperCase(),
101
- },
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"),
102
690
  });
691
+
692
+ expect(
693
+ await action.isActionStepValid(actionStep, { hash, chainId })
694
+ ).toBe(true);
103
695
  });
104
696
 
105
- test('can get all action steps', async () => {
106
- const action = await loadFixture(cloneEventAction(fixtures, erc721));
107
- const steps = await action.getActionSteps();
108
- expect(steps.length).toBe(1);
109
- const step = steps.at(0)!;
110
- step.targetContract = step.targetContract.toUpperCase() as Hex;
111
- step.actionParameter.filterData =
112
- step.actionParameter.filterData.toUpperCase() as Hex;
113
- expect(step).toMatchObject({
114
- signature: selectors['Transfer(address,address,uint256)'] as Hex,
115
- signatureType: SignatureType.EVENT,
116
- actionType: 0,
117
- targetContract: erc721.assertValidAddress().toUpperCase(),
118
- actionParameter: {
119
- filterType: FilterType.EQUAL,
120
- fieldType: PrimitiveType.ADDRESS,
121
- fieldIndex: 2,
122
- filterData: accounts.at(1)!.account.toUpperCase(),
123
- },
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"),
704
+ });
705
+
706
+ const criteriaMatch = await action.isActionStepValid(actionStep, {
707
+ hash,
708
+ chainId,
124
709
  });
710
+
711
+ expect(criteriaMatch).toBe(true);
125
712
  });
126
713
 
127
- test('can get the total number of action steps', async () => {
128
- const action = await loadFixture(cloneEventAction(fixtures, erc721));
129
- const count = await action.getActionStepsCount();
130
- 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
+ }
131
737
  });
132
738
 
133
- test('can get the action claimant', async () => {
134
- const action = await loadFixture(cloneEventAction(fixtures, erc721));
135
- const claimant = await action.getActionClaimant();
136
- claimant.targetContract = claimant.targetContract.toUpperCase() as Hex;
137
- expect(claimant).toMatchObject({
138
- signatureType: SignatureType.EVENT,
139
- signature: selectors['Transfer(address,address,uint256)'] as Hex,
140
- fieldIndex: 2,
141
- targetContract: erc721.assertValidAddress().toUpperCase(),
142
- });
143
- });
144
-
145
- test('with no logs, does not validate', async () => {
146
- const action = await loadFixture(cloneEventAction(fixtures, erc721));
147
- expect(await action.validateActionSteps()).toBe(false);
148
- });
149
-
150
- test('with a correct log, validates', async () => {
151
- const action = await loadFixture(cloneEventAction(fixtures, erc721));
152
- const recipient = accounts.at(1)!.account;
153
- await erc721.approve(recipient, 1n);
154
- await erc721.transferFrom(defaultOptions.account.address, recipient, 1n);
155
- expect(await action.validateActionSteps()).toBe(true);
156
- });
157
-
158
- test('can supply your own logs to validate against', async () => {
159
- const log = {
160
- eventName: 'Transfer',
161
- args: undefined,
162
- address: erc721.assertValidAddress(),
163
- blockHash:
164
- '0xbf602f988260519805d032be46d6ff97fbefbee6924b21097074d6d0bc34eced',
165
- blockNumber: 1203n,
166
- data: '0x',
167
- logIndex: 0,
168
- removed: false,
169
- topics: [
170
- '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
171
- '0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266',
172
- '0x00000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8',
173
- '0x0000000000000000000000000000000000000000000000000000000000000001',
174
- ],
175
- transactionHash:
176
- '0xff0e6ab0c4961ec14b7b40afec83ed7d7a77582683512a262e641d21f82efea5',
177
- transactionIndex: 0,
178
- } as Log;
179
- const action = await loadFixture(cloneEventAction(fixtures, erc721));
180
- expect(await action.validateActionSteps({ logs: [log] })).toBe(true);
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"),
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);
765
+ });
766
+
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);
789
+ });
790
+
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));
816
+ const recipient = accounts[1].account;
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);
181
827
  });
182
828
  });