@boostxyz/sdk 1.1.0-alpha.24 → 2.0.0-alpha.26

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 (134) hide show
  1. package/dist/Actions/Action.cjs +1 -1
  2. package/dist/Actions/Action.js +7 -7
  3. package/dist/Actions/EventAction.cjs +1 -1
  4. package/dist/Actions/EventAction.cjs.map +1 -1
  5. package/dist/Actions/EventAction.d.ts +7 -7
  6. package/dist/Actions/EventAction.d.ts.map +1 -1
  7. package/dist/Actions/EventAction.js +153 -152
  8. package/dist/Actions/EventAction.js.map +1 -1
  9. package/dist/AllowLists/AllowList.cjs +1 -1
  10. package/dist/AllowLists/AllowList.js +10 -10
  11. package/dist/AllowLists/SimpleAllowList.cjs +1 -1
  12. package/dist/AllowLists/SimpleAllowList.js +10 -10
  13. package/dist/AllowLists/SimpleDenyList.cjs +1 -1
  14. package/dist/AllowLists/SimpleDenyList.js +3 -3
  15. package/dist/Auth/PassthroughAuth.cjs +1 -1
  16. package/dist/Auth/PassthroughAuth.js +1 -1
  17. package/dist/BoostCore.cjs +2 -1
  18. package/dist/BoostCore.cjs.map +1 -1
  19. package/dist/BoostCore.d.ts +564 -1
  20. package/dist/BoostCore.d.ts.map +1 -1
  21. package/dist/BoostCore.js +1322 -29
  22. package/dist/BoostCore.js.map +1 -1
  23. package/dist/BoostRegistry.cjs +1 -1
  24. package/dist/BoostRegistry.js +27 -27
  25. package/dist/Budgets/Budget.cjs +1 -1
  26. package/dist/Budgets/Budget.js +2 -2
  27. package/dist/Budgets/ManagedBudget.cjs +1 -1
  28. package/dist/Budgets/ManagedBudget.js +23 -23
  29. package/dist/Deployable/DeployableTarget.cjs +1 -1
  30. package/dist/Deployable/DeployableTarget.js +1 -1
  31. package/dist/Deployable/DeployableTargetWithRBAC.cjs +1 -1
  32. package/dist/Deployable/DeployableTargetWithRBAC.js +23 -23
  33. package/dist/Incentives/AllowListIncentive.cjs +1 -1
  34. package/dist/Incentives/AllowListIncentive.js +8 -8
  35. package/dist/Incentives/CGDAIncentive.cjs +1 -1
  36. package/dist/Incentives/CGDAIncentive.js +12 -12
  37. package/dist/Incentives/ERC20Incentive.cjs +1 -1
  38. package/dist/Incentives/ERC20Incentive.js +16 -16
  39. package/dist/Incentives/ERC20VariableCriteriaIncentive.cjs +2 -0
  40. package/dist/Incentives/ERC20VariableCriteriaIncentive.cjs.map +1 -0
  41. package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts +42 -15
  42. package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts.map +1 -1
  43. package/dist/Incentives/ERC20VariableCriteriaIncentive.js +188 -0
  44. package/dist/Incentives/ERC20VariableCriteriaIncentive.js.map +1 -0
  45. package/dist/Incentives/ERC20VariableIncentive.cjs +2 -0
  46. package/dist/Incentives/ERC20VariableIncentive.cjs.map +1 -0
  47. package/dist/Incentives/ERC20VariableIncentive.d.ts +7 -5
  48. package/dist/Incentives/ERC20VariableIncentive.d.ts.map +1 -1
  49. package/dist/{Incentive-rM5nKznp.js → Incentives/ERC20VariableIncentive.js} +42 -67
  50. package/dist/Incentives/ERC20VariableIncentive.js.map +1 -0
  51. package/dist/Incentives/Incentive.cjs +1 -1
  52. package/dist/Incentives/Incentive.cjs.map +1 -1
  53. package/dist/Incentives/Incentive.d.ts +552 -3
  54. package/dist/Incentives/Incentive.d.ts.map +1 -1
  55. package/dist/Incentives/Incentive.js +40 -16
  56. package/dist/Incentives/Incentive.js.map +1 -1
  57. package/dist/Incentives/PointsIncentive.cjs +1 -1
  58. package/dist/Incentives/PointsIncentive.js +8 -8
  59. package/dist/{SimpleDenyList-DNj5qDWM.cjs → SimpleDenyList-BdlpZdDz.cjs} +2 -2
  60. package/dist/{SimpleDenyList-DNj5qDWM.cjs.map → SimpleDenyList-BdlpZdDz.cjs.map} +1 -1
  61. package/dist/{SimpleDenyList-BDXpY74P.js → SimpleDenyList-D0cyVUVv.js} +16 -16
  62. package/dist/{SimpleDenyList-BDXpY74P.js.map → SimpleDenyList-D0cyVUVv.js.map} +1 -1
  63. package/dist/Validators/LimitedSignerValidator.cjs +2 -0
  64. package/dist/Validators/LimitedSignerValidator.cjs.map +1 -0
  65. package/dist/Validators/LimitedSignerValidator.d.ts +806 -0
  66. package/dist/Validators/LimitedSignerValidator.d.ts.map +1 -0
  67. package/dist/Validators/LimitedSignerValidator.js +299 -0
  68. package/dist/Validators/LimitedSignerValidator.js.map +1 -0
  69. package/dist/Validators/SignerValidator.cjs +1 -1
  70. package/dist/Validators/SignerValidator.cjs.map +1 -1
  71. package/dist/Validators/SignerValidator.d.ts +2 -2
  72. package/dist/Validators/SignerValidator.d.ts.map +1 -1
  73. package/dist/Validators/SignerValidator.js +39 -41
  74. package/dist/Validators/SignerValidator.js.map +1 -1
  75. package/dist/Validators/Validator.cjs +1 -1
  76. package/dist/Validators/Validator.cjs.map +1 -1
  77. package/dist/Validators/Validator.d.ts +22 -2
  78. package/dist/Validators/Validator.d.ts.map +1 -1
  79. package/dist/Validators/Validator.js +26 -17
  80. package/dist/Validators/Validator.js.map +1 -1
  81. package/dist/{componentInterfaces-BBCFkrZv.js → componentInterfaces-bIVo8eyA.js} +9 -9
  82. package/dist/componentInterfaces-bIVo8eyA.js.map +1 -0
  83. package/dist/{deployments-fJsWblwS.js → deployments-Ccx1MtoK.js} +5 -5
  84. package/dist/deployments-Ccx1MtoK.js.map +1 -0
  85. package/dist/{generated-CsNyWPKA.js → generated-BAKNSOjJ.js} +661 -381
  86. package/dist/generated-BAKNSOjJ.js.map +1 -0
  87. package/dist/generated-Cqn4wS01.cjs +3 -0
  88. package/dist/generated-Cqn4wS01.cjs.map +1 -0
  89. package/dist/index.cjs +1 -1
  90. package/dist/index.d.ts +1 -0
  91. package/dist/index.d.ts.map +1 -1
  92. package/dist/index.js +150 -138
  93. package/dist/index.js.map +1 -1
  94. package/dist/utils.cjs +1 -1
  95. package/dist/utils.cjs.map +1 -1
  96. package/dist/utils.d.ts +10 -0
  97. package/dist/utils.d.ts.map +1 -1
  98. package/dist/utils.js +27 -26
  99. package/dist/utils.js.map +1 -1
  100. package/package.json +21 -5
  101. package/src/Actions/EventAction.ts +29 -27
  102. package/src/BoostCore.test.ts +3 -3
  103. package/src/BoostCore.ts +51 -5
  104. package/src/Incentives/AllowListIncentive.test.ts +19 -21
  105. package/src/Incentives/CGDAIncentive.test.ts +20 -22
  106. package/src/Incentives/ERC1155Incentive.test.ts +14 -15
  107. package/src/Incentives/ERC20Incentive.test.ts +17 -19
  108. package/src/Incentives/ERC20VariableCriteriaIncentive.test.ts +62 -10
  109. package/src/Incentives/ERC20VariableCriteriaIncentive.ts +79 -37
  110. package/src/Incentives/ERC20VariableIncentive.test.ts +16 -18
  111. package/src/Incentives/ERC20VariableIncentive.ts +16 -8
  112. package/src/Incentives/Incentive.ts +4 -1
  113. package/src/Incentives/PointsIncentive.test.ts +3 -5
  114. package/src/Validators/LimitedSignerValidator.test.ts +223 -0
  115. package/src/Validators/LimitedSignerValidator.ts +707 -0
  116. package/src/Validators/SignerValidator.test.ts +21 -22
  117. package/src/Validators/SignerValidator.ts +3 -4
  118. package/src/Validators/Validator.test.ts +7 -1
  119. package/src/Validators/Validator.ts +30 -3
  120. package/src/index.test.ts +2 -0
  121. package/src/index.ts +1 -0
  122. package/src/utils.ts +11 -0
  123. package/dist/BoostCore-Btl5BdAs.cjs +0 -3
  124. package/dist/BoostCore-Btl5BdAs.cjs.map +0 -1
  125. package/dist/BoostCore-CD56zbYX.js +0 -2641
  126. package/dist/BoostCore-CD56zbYX.js.map +0 -1
  127. package/dist/Incentive-CcnOIc8L.cjs +0 -2
  128. package/dist/Incentive-CcnOIc8L.cjs.map +0 -1
  129. package/dist/Incentive-rM5nKznp.js.map +0 -1
  130. package/dist/componentInterfaces-BBCFkrZv.js.map +0 -1
  131. package/dist/deployments-fJsWblwS.js.map +0 -1
  132. package/dist/generated-CsNyWPKA.js.map +0 -1
  133. package/dist/generated-DHerxf1y.cjs +0 -3
  134. package/dist/generated-DHerxf1y.cjs.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boostxyz/sdk",
3
- "version": "1.1.0-alpha.24",
3
+ "version": "2.0.0-alpha.26",
4
4
  "license": "GPL-3.0-or-later",
5
5
  "type": "module",
6
6
  "files": [
@@ -169,6 +169,18 @@
169
169
  "node": "./dist/Incentives/ERC20Incentive.js",
170
170
  "types": "./dist/Incentives/ERC20Incentive.d.ts"
171
171
  },
172
+ "./Incentives/ERC20VariableIncentive": {
173
+ "require": "./dist/Incentives/ERC20VariableIncentive.cjs",
174
+ "import": "./dist/Incentives/ERC20VariableIncentive.js",
175
+ "node": "./dist/Incentives/ERC20VariableIncentive.js",
176
+ "types": "./dist/Incentives/ERC20VariableIncentive.d.ts"
177
+ },
178
+ "./Incentives/ERC20VariableCriteriaIncentive": {
179
+ "require": "./dist/Incentives/ERC20VariableCriteriaIncentive.cjs",
180
+ "import": "./dist/Incentives/ERC20VariableCriteriaIncentive.js",
181
+ "node": "./dist/Incentives/ERC20VariableCriteriaIncentive.js",
182
+ "types": "./dist/Incentives/ERC20VariableCriteriaIncentive.d.ts"
183
+ },
172
184
  "./Incentives/Incentive": {
173
185
  "require": "./dist/Incentives/Incentive.cjs",
174
186
  "import": "./dist/Incentives/Incentive.js",
@@ -192,15 +204,19 @@
192
204
  "import": "./dist/Validators/SignerValidator.js",
193
205
  "node": "./dist/Validators/SignerValidator.js",
194
206
  "types": "./dist/Validators/SignerValidator.d.ts"
207
+ },
208
+ "./Validators/LimitedSignerValidator": {
209
+ "require": "./dist/Validators/LimitedSignerValidator.cjs",
210
+ "import": "./dist/Validators/LimitedSignerValidator.js",
211
+ "node": "./dist/Validators/LimitedSignerValidator.js",
212
+ "types": "./dist/Validators/LimitedSignerValidator.d.ts"
195
213
  }
196
214
  },
197
215
  "dependencies": {
198
- "ts-pattern": "5.4.0",
199
- "@boostxyz/signatures": "1.1.0-alpha.23"
216
+ "ts-pattern": "5.4.0"
200
217
  },
201
218
  "optionalDependencies": {
202
- "@boostxyz/evm": "1.1.0-alpha.23",
203
- "@boostxyz/signatures": "1.1.0-alpha.23"
219
+ "@boostxyz/evm": "2.0.0-alpha.24"
204
220
  },
205
221
  "peerDependencies": {
206
222
  "@wagmi/core": "2.x",
@@ -47,6 +47,7 @@ import {
47
47
  ValidationAbiMissingError,
48
48
  } from '../errors';
49
49
  import {
50
+ CheatCodes,
50
51
  type Overwrite,
51
52
  type ReadParams,
52
53
  RegistryType,
@@ -222,12 +223,13 @@ export interface ActionStep {
222
223
  * @property {AbiEvent | AbiFunction} [abiItem] - Optional ABI item definition.
223
224
  * @property {EventLogs} [logs] - Event logs to validate against. Required if 'hash' is not provided.
224
225
  * @property {Hex} [hash] - Transaction hash to validate against. Required if 'logs' is not provided.
225
- * @property {number} [chainId] - Chain ID for the transaction. Required if 'hash' is provided.
226
+ * @property {number} [chainId] - Chain ID for the transaction.
226
227
  */
227
228
  export type ValidateActionStepParams = {
228
229
  knownSignatures: Record<Hex, AbiEvent | AbiFunction>;
229
230
  abiItem?: AbiEvent | AbiFunction;
230
- } & ({ logs: EventLogs } | { hash: Hex; chainId: number });
231
+ chainId: number;
232
+ } & ({ logs: EventLogs } | { hash: Hex });
231
233
 
232
234
  /**
233
235
  * You can either supply a simplified version of the payload, or one that explicitly declares action steps.
@@ -483,7 +485,7 @@ export class EventAction extends DeployableTarget<
483
485
  /**
484
486
  * Derives the action claimant address from a transaction based on the provided ActionClaimant configuration.
485
487
  * This method supports both event-based and function-based claimant derivation.
486
- * **Important**: The claimant is considered to be `transaction.from` when `claimant.fieldIndex` is 255.
488
+ * **Important**: The claimant is considered to be `transaction.from` when `claimant.fieldIndex` is 255 using CheatCodes enum.
487
489
  * This may have unintended side effects for bridged transactions and SCW transactions, so these are considered unsupported use cases for the time being.
488
490
  *
489
491
  ** @example
@@ -520,10 +522,11 @@ export class EventAction extends DeployableTarget<
520
522
  ): Promise<Address | undefined> {
521
523
  // find message sender and return it
522
524
  // WARNING: this is error prone in bridged transactions and SCW transactions, as this will return exit node
523
- if (claimant.fieldIndex === 255) {
525
+ if (claimant.fieldIndex === CheatCodes.TX_SENDER_CLAIMANT) {
524
526
  if ('hash' in params) {
525
527
  const transaction = await getTransaction(this._config, {
526
528
  hash: params.hash,
529
+ chainId: params.chainId,
527
530
  });
528
531
  return transaction.from;
529
532
  }
@@ -532,6 +535,7 @@ export class EventAction extends DeployableTarget<
532
535
  if (log.transactionHash) {
533
536
  const transaction = await getTransaction(this._config, {
534
537
  hash: log.transactionHash,
538
+ chainId: claimant.chainid,
535
539
  });
536
540
  return transaction.from;
537
541
  }
@@ -582,13 +586,10 @@ export class EventAction extends DeployableTarget<
582
586
  }
583
587
  return address;
584
588
  }
585
- if (
586
- claimant.signatureType === SignatureType.FUNC &&
587
- 'hash' in params &&
588
- 'chainId' in params
589
- ) {
589
+ if (claimant.signatureType === SignatureType.FUNC && 'hash' in params) {
590
590
  const transaction = await getTransaction(this._config, {
591
591
  hash: params.hash,
592
+ chainId: params.chainId,
592
593
  });
593
594
  if (!isAddressEqual(transaction.to!, claimant.targetContract)) return;
594
595
  let func: AbiFunction;
@@ -698,11 +699,9 @@ export class EventAction extends DeployableTarget<
698
699
  return this.isActionEventValid(actionStep, params.logs);
699
700
  }
700
701
 
701
- const client = this._config.getClient({
702
- chainId: params.chainId,
703
- }) as PublicClient;
704
- const receipt = await client.getTransactionReceipt({
702
+ const receipt = await getTransactionReceipt(this._config, {
705
703
  hash: params.hash,
704
+ chainId: params.chainId,
706
705
  });
707
706
  const decodedLogs = receipt.logs.map((log) => {
708
707
  const { eventName, args } = decodeEventLog({
@@ -718,11 +717,9 @@ export class EventAction extends DeployableTarget<
718
717
  }
719
718
  if (actionStep.signatureType === SignatureType.FUNC) {
720
719
  if ('hash' in params && 'chainId' in params) {
721
- const client = this._config.getClient({
722
- chainId: params.chainId,
723
- }) as PublicClient;
724
- const transaction = await client.getTransaction({
720
+ const transaction = await getTransaction(this._config, {
725
721
  hash: params.hash,
722
+ chainId: params.chainId,
726
723
  });
727
724
  return this.isActionFunctionValid(actionStep, transaction, params);
728
725
  }
@@ -828,7 +825,7 @@ export class EventAction extends DeployableTarget<
828
825
  if (
829
826
  criteria.filterType === FilterType.EQUAL &&
830
827
  criteria.fieldType === PrimitiveType.BYTES &&
831
- criteria.fieldIndex === 255
828
+ criteria.fieldIndex === CheatCodes.ANY_ACTION_PARAM
832
829
  ) {
833
830
  return true;
834
831
  }
@@ -932,7 +929,7 @@ export class EventAction extends DeployableTarget<
932
929
 
933
930
  /**
934
931
  * Validates a {@link Log} against a given criteria.
935
- * If the criteria's fieldIndex is 255, it is reserved for anyValidation
932
+ * If the criteria's fieldIndex is 255 (using CheatCodes enum), it is reserved for anyValidation
936
933
  *
937
934
  * @param {Criteria} criteria - The criteria to validate against.
938
935
  * @param {Log} log - The Viem event log.
@@ -944,7 +941,8 @@ export class EventAction extends DeployableTarget<
944
941
  ): boolean {
945
942
  if (
946
943
  !Array.isArray(log.args) ||
947
- (log.args.length <= criteria.fieldIndex && criteria.fieldIndex !== 255)
944
+ (log.args.length <= criteria.fieldIndex &&
945
+ criteria.fieldIndex !== CheatCodes.ANY_ACTION_PARAM)
948
946
  ) {
949
947
  throw new DecodedArgsMalformedError({
950
948
  log,
@@ -954,7 +952,9 @@ export class EventAction extends DeployableTarget<
954
952
  }
955
953
 
956
954
  const fieldValue =
957
- criteria.fieldIndex === 255 ? zeroHash : log.args.at(criteria.fieldIndex);
955
+ criteria.fieldIndex === CheatCodes.ANY_ACTION_PARAM
956
+ ? zeroHash
957
+ : log.args.at(criteria.fieldIndex);
958
958
 
959
959
  if (fieldValue === undefined) {
960
960
  throw new FieldValueUndefinedError({ log, criteria, fieldValue });
@@ -964,7 +964,7 @@ export class EventAction extends DeployableTarget<
964
964
 
965
965
  /**
966
966
  * Validates a function's decoded arguments against a given criteria.
967
- * If the criteria's fieldIndex is 255, it is reserved for anyValidation
967
+ * If the criteria's fieldIndex is 255 (using CheatCodes enum), it is reserved for anyValidation
968
968
  *
969
969
  * @param {Criteria} criteria - The criteria to validate against.
970
970
  * @param {unknown[]} decodedArgs - The decoded arguments of the function call.
@@ -975,7 +975,9 @@ export class EventAction extends DeployableTarget<
975
975
  decodedArgs: readonly (string | bigint)[],
976
976
  ): boolean {
977
977
  const fieldValue =
978
- criteria.fieldIndex === 255 ? zeroHash : decodedArgs[criteria.fieldIndex];
978
+ criteria.fieldIndex === CheatCodes.ANY_ACTION_PARAM
979
+ ? zeroHash
980
+ : decodedArgs[criteria.fieldIndex];
979
981
  if (fieldValue === undefined) {
980
982
  throw new FieldValueUndefinedError({
981
983
  criteria,
@@ -1247,7 +1249,7 @@ export function prepareEventActionPayload({
1247
1249
  * This function returns a Criteria object with the following properties:
1248
1250
  * - filterType: Set to EQUAL for exact matching
1249
1251
  * - fieldType: Set to BYTES to handle any data type
1250
- * - fieldIndex: Set to 255, which is typically used to indicate "any" or "all" in this context
1252
+ * - fieldIndex: Set to 255, which is typically used to indicate "any" or "all" in this context using CheatCodes enum
1251
1253
  * - filterData: Set to zeroHash (0x0000...0000)
1252
1254
  *
1253
1255
  * @returns {Criteria} A Criteria object that can be used to match any action parameter
@@ -1264,7 +1266,7 @@ export function anyActionParameter(): Criteria {
1264
1266
  return {
1265
1267
  filterType: FilterType.EQUAL,
1266
1268
  fieldType: PrimitiveType.BYTES,
1267
- fieldIndex: 255,
1269
+ fieldIndex: CheatCodes.ANY_ACTION_PARAM,
1268
1270
  filterData: zeroHash,
1269
1271
  };
1270
1272
  }
@@ -1277,7 +1279,7 @@ export function anyActionParameter(): Criteria {
1277
1279
  * The returned ActionClaimant has the following properties:
1278
1280
  * - signatureType: Set to SignatureType.EVENT (though it doesn't matter for this case)
1279
1281
  * - signature: Set to zeroHash (0x0000...0000)
1280
- * - fieldIndex: Set to 255, indicating "any" field
1282
+ * - fieldIndex: Set to 255, indicating "any" field using CheatCodes enum
1281
1283
  * - targetContract: Set to zeroAddress (0x0000...0000)
1282
1284
  * - chainid: Set to 0, indicating it's valid for any chain
1283
1285
  *
@@ -1297,7 +1299,7 @@ export function transactionSenderClaimant(): ActionClaimant {
1297
1299
  return {
1298
1300
  signatureType: SignatureType.EVENT,
1299
1301
  signature: zeroHash,
1300
- fieldIndex: 255,
1302
+ fieldIndex: CheatCodes.TX_SENDER_CLAIMANT,
1301
1303
  targetContract: zeroAddress,
1302
1304
  chainid: 0,
1303
1305
  };
@@ -17,6 +17,7 @@ import type { ERC20Incentive } from "./Incentives/ERC20Incentive";
17
17
  import { StrategyType } from "./claiming";
18
18
  import { BoostNotFoundError, IncentiveNotCloneableError } from "./errors";
19
19
  import { bytes4 } from "./utils";
20
+ import { BoostValidatorEOA } from "./Validators/Validator";
20
21
 
21
22
  let fixtures: Fixtures, budgets: BudgetFixtures;
22
23
 
@@ -843,7 +844,7 @@ describe("BoostCore", () => {
843
844
  expect(validator.payload?.validatorCaller).toBe(core.assertValidAddress());
844
845
 
845
846
  // expect current account to be a signer
846
- const signer = await validator.signers(defaultOptions.account.address);
847
+ const signer = await validator.signers(BoostValidatorEOA.TESTNET);
847
848
  expect(signer).toBeDefined();
848
849
  expect(signer).toBe(true);
849
850
  });
@@ -867,12 +868,11 @@ describe("BoostCore", () => {
867
868
 
868
869
  const claimant = trustedSigner.account;
869
870
  const incentiveData = pad("0xdef456232173821931823712381232131391321934");
870
- const incentiveQuantity = 1;
871
871
  const claimDataPayload = await boost.validator.encodeClaimData({
872
872
  signer: trustedSigner,
873
873
  incentiveData,
874
874
  chainId: defaultOptions.config.chains[0].id,
875
- incentiveQuantity,
875
+ incentiveQuantity: boost.incentives.length,
876
876
  claimant,
877
877
  boostId: boost.id,
878
878
  });
package/src/BoostCore.ts CHANGED
@@ -21,6 +21,7 @@ import { bytecode } from '@boostxyz/evm/artifacts/contracts/BoostCore.sol/BoostC
21
21
  import {
22
22
  type GetTransactionReceiptParameters,
23
23
  getAccount,
24
+ getChains,
24
25
  getTransactionReceipt,
25
26
  waitForTransactionReceipt,
26
27
  } from '@wagmi/core';
@@ -93,17 +94,26 @@ import {
93
94
  PointsIncentive,
94
95
  type PointsIncentivePayload,
95
96
  } from './Incentives/PointsIncentive';
97
+ import {
98
+ LimitedSignerValidator,
99
+ type LimitedSignerValidatorPayload,
100
+ } from './Validators/LimitedSignerValidator';
96
101
  import {
97
102
  SignerValidator,
98
103
  type SignerValidatorPayload,
99
104
  } from './Validators/SignerValidator';
100
- import { type Validator, validatorFromAddress } from './Validators/Validator';
105
+ import {
106
+ BoostValidatorEOA,
107
+ type Validator,
108
+ validatorFromAddress,
109
+ } from './Validators/Validator';
101
110
  import {
102
111
  BoostCoreNoIdentifierEmitted,
103
112
  BoostNotFoundError,
104
113
  BudgetMustAuthorizeBoostCore,
105
114
  DeployableUnknownOwnerProvidedError,
106
115
  IncentiveNotCloneableError,
116
+ InvalidProtocolChainIdError,
107
117
  MustInitializeBudgetError,
108
118
  } from './errors';
109
119
  import {
@@ -347,8 +357,6 @@ export class BoostCore extends Deployable<
347
357
  options,
348
358
  );
349
359
 
350
- console.log(onChainPayload);
351
-
352
360
  const boostHash = await boostFactory(options.config, {
353
361
  ...this.optionallyAttachAccount(options.account),
354
362
  // biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
@@ -441,9 +449,24 @@ export class BoostCore extends Deployable<
441
449
  }
442
450
  }
443
451
 
452
+ // If not providing a custom validator, use either Boost's mainnet or testnet EOA, depending on provided chain id and given chain configurations
444
453
  if (!payload.validator) {
454
+ const chains = getChains(options.config).filter(
455
+ (chain) => !!this.addresses[chain.id] && chain.id === chainId,
456
+ );
457
+ const chain = chains.at(0);
458
+ if (!chain)
459
+ throw new InvalidProtocolChainIdError(
460
+ chainId,
461
+ Object.keys(this.addresses).map(Number),
462
+ );
463
+ const testnet = chain.testnet || chain.id === 31337;
445
464
  payload.validator = this.SignerValidator({
446
- signers: [payload.owner],
465
+ signers: [
466
+ (testnet
467
+ ? BoostValidatorEOA.TESTNET
468
+ : BoostValidatorEOA.MAINNET) as unknown as Address,
469
+ ],
447
470
  validatorCaller: coreAddress,
448
471
  });
449
472
  }
@@ -800,7 +823,7 @@ export class BoostCore extends Deployable<
800
823
  budget,
801
824
  validator,
802
825
  allowList,
803
- incentives,
826
+ incentives: incentives as Incentive[],
804
827
  protocolFee,
805
828
  maxParticipants,
806
829
  owner,
@@ -1372,6 +1395,29 @@ export class BoostCore extends Deployable<
1372
1395
  );
1373
1396
  }
1374
1397
 
1398
+ /**
1399
+ * Bound {@link LimitedSignerValidator} constructor that reuses the same configuration as the Boost Core instance.
1400
+ *
1401
+ * @example
1402
+ * ```ts
1403
+ * const validator = core.LimitedSignerValidator({ ... }) // is roughly equivalent to
1404
+ * const validator = new LimitedSignerValidator({ config: core._config, account: core._account }, { ... })
1405
+ * ```
1406
+ * @param {DeployablePayloadOrAddress<LimitedSignerValidatorPayload>} options
1407
+ * @param {?boolean} [isBase]
1408
+ * @returns {LimitedSignerValidator}
1409
+ */
1410
+ LimitedSignerValidator(
1411
+ options: DeployablePayloadOrAddress<LimitedSignerValidatorPayload>,
1412
+ isBase?: boolean,
1413
+ ) {
1414
+ return new LimitedSignerValidator(
1415
+ { config: this._config, account: this._account },
1416
+ options,
1417
+ isBase,
1418
+ );
1419
+ }
1420
+
1375
1421
  /**
1376
1422
  * Bound {@link ERC20VariableCriteriaIncentive} constructor that reuses the same configuration as the Boost Core instance.
1377
1423
  *
@@ -1,15 +1,15 @@
1
- import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
2
- import { isAddress, pad, parseEther, zeroAddress } from 'viem';
3
- import { beforeAll, describe, expect, test } from 'vitest';
4
- import { accounts } from '@boostxyz/test/accounts';
1
+ import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
2
+ import { isAddress, pad, parseEther, zeroAddress } from "viem";
3
+ import { beforeAll, describe, expect, test } from "vitest";
4
+ import { accounts } from "@boostxyz/test/accounts";
5
5
  import {
6
6
  type Fixtures,
7
7
  defaultOptions,
8
8
  deployFixtures,
9
9
  freshBoost,
10
- } from '@boostxyz/test/helpers';
11
- import { PointsIncentive } from './PointsIncentive';
12
- import { Roles } from '../Deployable/DeployableTargetWithRBAC';
10
+ } from "@boostxyz/test/helpers";
11
+ import { PointsIncentive } from "./PointsIncentive";
12
+ import { Roles } from "../Deployable/DeployableTargetWithRBAC";
13
13
 
14
14
  let fixtures: Fixtures;
15
15
 
@@ -25,15 +25,15 @@ function freshAllowList(fixtures: Fixtures) {
25
25
  };
26
26
  }
27
27
 
28
- describe('AllowListIncentive', () => {
28
+ describe("AllowListIncentive", () => {
29
29
  beforeAll(async () => {
30
30
  fixtures = await loadFixture(deployFixtures(defaultOptions));
31
31
  });
32
32
 
33
- test('can successfully be deployed', async () => {
33
+ test("can successfully be deployed", async () => {
34
34
  const action = new PointsIncentive(defaultOptions, {
35
35
  venue: zeroAddress,
36
- selector: '0xdeadb33f',
36
+ selector: "0xdeadb33f",
37
37
  reward: 1n,
38
38
  limit: 1n,
39
39
  });
@@ -41,7 +41,7 @@ describe('AllowListIncentive', () => {
41
41
  expect(isAddress(action.assertValidAddress())).toBe(true);
42
42
  });
43
43
 
44
- test('can claim', async () => {
44
+ test("can claim", async () => {
45
45
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
46
46
  const referrer = accounts.at(1)?.account!;
47
47
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
@@ -63,15 +63,14 @@ describe('AllowListIncentive', () => {
63
63
  );
64
64
 
65
65
  const claimant = trustedSigner.account;
66
- const incentiveData = pad('0xdef456232173821931823712381232131391321934');
66
+ const incentiveData = pad("0xdef456232173821931823712381232131391321934");
67
67
  console.log(claimant);
68
68
 
69
- const incentiveQuantity = 1;
70
69
  const claimDataPayload = await boost.validator.encodeClaimData({
71
70
  signer: trustedSigner,
72
71
  incentiveData,
73
72
  chainId: defaultOptions.config.chains[0].id,
74
- incentiveQuantity,
73
+ incentiveQuantity: boost.incentives.length,
75
74
  claimant,
76
75
  boostId: boost.id,
77
76
  });
@@ -82,12 +81,12 @@ describe('AllowListIncentive', () => {
82
81
  0n,
83
82
  referrer,
84
83
  claimDataPayload,
85
- { value: parseEther('0.000075'), account: trustedSigner.privateKey },
84
+ { value: parseEther("0.000075"), account: trustedSigner.privateKey },
86
85
  );
87
86
  expect(await allowList.isAllowed(trustedSigner.account)).toBe(true);
88
87
  });
89
88
 
90
- test('cannot claim twice', async () => {
89
+ test("cannot claim twice", async () => {
91
90
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
92
91
  const referrer = accounts.at(1)?.account!;
93
92
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
@@ -107,16 +106,15 @@ describe('AllowListIncentive', () => {
107
106
  [allowListIncentive.assertValidAddress()],
108
107
  [Roles.MANAGER],
109
108
  );
110
- const incentiveQuantity = 1;
111
109
  const claimant = trustedSigner.account;
112
- const incentiveData = pad('0xdef456232173821931823712381232131391321934');
110
+ const incentiveData = pad("0xdef456232173821931823712381232131391321934");
113
111
  console.log(claimant);
114
112
 
115
113
  const claimDataPayload = await boost.validator.encodeClaimData({
116
114
  signer: trustedSigner,
117
115
  incentiveData,
118
116
  chainId: defaultOptions.config.chains[0].id,
119
- incentiveQuantity,
117
+ incentiveQuantity: boost.incentives.length,
120
118
  claimant,
121
119
  boostId: boost.id,
122
120
  });
@@ -126,7 +124,7 @@ describe('AllowListIncentive', () => {
126
124
  0n,
127
125
  referrer,
128
126
  claimDataPayload,
129
- { value: parseEther('0.000075'), account: trustedSigner.privateKey },
127
+ { value: parseEther("0.000075"), account: trustedSigner.privateKey },
130
128
  );
131
129
  try {
132
130
  await fixtures.core.claimIncentive(
@@ -134,7 +132,7 @@ describe('AllowListIncentive', () => {
134
132
  0n,
135
133
  referrer,
136
134
  claimDataPayload,
137
- { value: parseEther('0.000075'), account: trustedSigner.privateKey },
135
+ { value: parseEther("0.000075"), account: trustedSigner.privateKey },
138
136
  );
139
137
  } catch (e) {
140
138
  expect(e).toBeInstanceOf(Error);
@@ -1,8 +1,8 @@
1
- import { readMockErc20BalanceOf } from '@boostxyz/evm';
2
- import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
3
- import { isAddress, pad, parseEther, zeroAddress } from 'viem';
4
- import { beforeAll, beforeEach, describe, expect, test } from 'vitest';
5
- import { accounts } from '@boostxyz/test/accounts';
1
+ import { readMockErc20BalanceOf } from "@boostxyz/evm";
2
+ import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
3
+ import { isAddress, pad, parseEther, zeroAddress } from "viem";
4
+ import { beforeAll, beforeEach, describe, expect, test } from "vitest";
5
+ import { accounts } from "@boostxyz/test/accounts";
6
6
  import {
7
7
  type BudgetFixtures,
8
8
  type Fixtures,
@@ -10,12 +10,12 @@ import {
10
10
  deployFixtures,
11
11
  freshBoost,
12
12
  fundBudget,
13
- } from '@boostxyz/test/helpers';
14
- import { CGDAIncentive } from './CGDAIncentive';
13
+ } from "@boostxyz/test/helpers";
14
+ import { CGDAIncentive } from "./CGDAIncentive";
15
15
 
16
16
  let fixtures: Fixtures, budgets: BudgetFixtures;
17
17
 
18
- describe('CGDAIncentive', () => {
18
+ describe("CGDAIncentive", () => {
19
19
  beforeAll(async () => {
20
20
  fixtures = await loadFixture(deployFixtures(defaultOptions));
21
21
  });
@@ -24,20 +24,20 @@ describe('CGDAIncentive', () => {
24
24
  budgets = await loadFixture(fundBudget(defaultOptions, fixtures));
25
25
  });
26
26
 
27
- test('can successfully be deployed', async () => {
27
+ test("can successfully be deployed", async () => {
28
28
  const action = new CGDAIncentive(defaultOptions, {
29
29
  asset: budgets.erc20.assertValidAddress(),
30
30
  initialReward: 1n,
31
31
  totalBudget: 10n,
32
32
  rewardBoost: 1n,
33
33
  rewardDecay: 1n,
34
- manager: budgets.budget.address || zeroAddress
34
+ manager: budgets.budget.address || zeroAddress,
35
35
  });
36
36
  await action.deploy();
37
37
  expect(isAddress(action.assertValidAddress())).toBe(true);
38
38
  });
39
39
 
40
- test('can claim', async () => {
40
+ test("can claim", async () => {
41
41
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
42
42
  const referrer = accounts.at(1)!.account!;
43
43
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
@@ -56,14 +56,13 @@ describe('CGDAIncentive', () => {
56
56
  });
57
57
 
58
58
  const claimant = trustedSigner.account;
59
- const incentiveData = pad('0xdef456232173821931823712381232131391321934');
59
+ const incentiveData = pad("0xdef456232173821931823712381232131391321934");
60
60
 
61
- const incentiveQuantity = 1;
62
61
  const claimDataPayload = await boost.validator.encodeClaimData({
63
62
  signer: trustedSigner,
64
63
  incentiveData,
65
64
  chainId: defaultOptions.config.chains[0].id,
66
- incentiveQuantity,
65
+ incentiveQuantity: boost.incentives.length,
67
66
  claimant,
68
67
  boostId: boost.id,
69
68
  });
@@ -73,7 +72,7 @@ describe('CGDAIncentive', () => {
73
72
  0n,
74
73
  referrer,
75
74
  claimDataPayload,
76
- { value: parseEther('0.000075') },
75
+ { value: parseEther("0.000075") },
77
76
  );
78
77
  expect(
79
78
  await readMockErc20BalanceOf(defaultOptions.config, {
@@ -83,7 +82,7 @@ describe('CGDAIncentive', () => {
83
82
  ).toBe(1n);
84
83
  });
85
84
 
86
- test('cannot claim twice', async () => {
85
+ test("cannot claim twice", async () => {
87
86
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
88
87
  const referrer = accounts.at(1)!.account!;
89
88
  // biome-ignore lint/style/noNonNullAssertion: we know this is defined
@@ -94,7 +93,7 @@ describe('CGDAIncentive', () => {
94
93
  totalBudget: 10n,
95
94
  rewardBoost: 1n,
96
95
  rewardDecay: 1n,
97
- manager: budgets.budget.address || zeroAddress
96
+ manager: budgets.budget.address || zeroAddress,
98
97
  });
99
98
  const boost = await freshBoost(fixtures, {
100
99
  budget: budgets.budget,
@@ -102,13 +101,12 @@ describe('CGDAIncentive', () => {
102
101
  });
103
102
 
104
103
  const claimant = trustedSigner.account;
105
- const incentiveData = pad('0xdef456232173821931823712381232131391321934');
106
- const incentiveQuantity = 1;
104
+ const incentiveData = pad("0xdef456232173821931823712381232131391321934");
107
105
  const claimDataPayload = await boost.validator.encodeClaimData({
108
106
  signer: trustedSigner,
109
107
  incentiveData,
110
108
  chainId: defaultOptions.config.chains[0].id,
111
- incentiveQuantity,
109
+ incentiveQuantity: boost.incentives.length,
112
110
  claimant,
113
111
  boostId: boost.id,
114
112
  });
@@ -118,7 +116,7 @@ describe('CGDAIncentive', () => {
118
116
  0n,
119
117
  referrer,
120
118
  claimDataPayload,
121
- { value: parseEther('0.000075') },
119
+ { value: parseEther("0.000075") },
122
120
  );
123
121
  try {
124
122
  await fixtures.core.claimIncentive(
@@ -126,7 +124,7 @@ describe('CGDAIncentive', () => {
126
124
  0n,
127
125
  referrer,
128
126
  claimDataPayload,
129
- { value: parseEther('0.000075') },
127
+ { value: parseEther("0.000075") },
130
128
  );
131
129
  } catch (e) {
132
130
  expect(e).toBeInstanceOf(Error);