@boostxyz/sdk 7.7.0 → 8.0.0-canary.0

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 (128) hide show
  1. package/dist/Actions/Action.cjs +1 -1
  2. package/dist/Actions/Action.js +1 -1
  3. package/dist/Actions/EventAction.cjs +1 -1
  4. package/dist/Actions/EventAction.cjs.map +1 -1
  5. package/dist/Actions/EventAction.d.ts +25 -4
  6. package/dist/Actions/EventAction.d.ts.map +1 -1
  7. package/dist/Actions/EventAction.js +208 -184
  8. package/dist/Actions/EventAction.js.map +1 -1
  9. package/dist/{AllowList-DiU7g4Hs.js → AllowList-CWqAYlwr.js} +28 -28
  10. package/dist/{AllowList-DiU7g4Hs.js.map → AllowList-CWqAYlwr.js.map} +1 -1
  11. package/dist/{AllowList-BJ9HQGFs.cjs → AllowList-Lpqz7tn9.cjs} +2 -2
  12. package/dist/{AllowList-BJ9HQGFs.cjs.map → AllowList-Lpqz7tn9.cjs.map} +1 -1
  13. package/dist/AllowLists/AllowList.cjs +1 -1
  14. package/dist/AllowLists/AllowList.js +3 -3
  15. package/dist/AllowLists/SimpleAllowList.cjs +1 -1
  16. package/dist/AllowLists/SimpleAllowList.js +8 -8
  17. package/dist/AllowLists/SimpleDenyList.cjs +1 -1
  18. package/dist/AllowLists/SimpleDenyList.js +3 -3
  19. package/dist/Auth/PassthroughAuth.cjs +1 -1
  20. package/dist/Auth/PassthroughAuth.js +1 -1
  21. package/dist/BoostCore.cjs +2 -2
  22. package/dist/BoostCore.cjs.map +1 -1
  23. package/dist/BoostCore.d.ts +106 -23
  24. package/dist/BoostCore.d.ts.map +1 -1
  25. package/dist/BoostCore.js +518 -451
  26. package/dist/BoostCore.js.map +1 -1
  27. package/dist/BoostRegistry.cjs +1 -1
  28. package/dist/BoostRegistry.js +46 -46
  29. package/dist/{Budget-YIhV65cc.js → Budget-BPPXnBAK.js} +36 -36
  30. package/dist/{Budget-YIhV65cc.js.map → Budget-BPPXnBAK.js.map} +1 -1
  31. package/dist/{Budget-D_zhh1rh.cjs → Budget-rZm-AY09.cjs} +2 -2
  32. package/dist/{Budget-D_zhh1rh.cjs.map → Budget-rZm-AY09.cjs.map} +1 -1
  33. package/dist/Budgets/Budget.cjs +1 -1
  34. package/dist/Budgets/Budget.js +2 -2
  35. package/dist/Budgets/ManagedBudget.cjs +1 -1
  36. package/dist/Budgets/ManagedBudget.js +24 -24
  37. package/dist/Deployable/Contract.cjs +1 -1
  38. package/dist/Deployable/Contract.cjs.map +1 -1
  39. package/dist/Deployable/Contract.d.ts +8 -0
  40. package/dist/Deployable/Contract.d.ts.map +1 -1
  41. package/dist/Deployable/Contract.js +14 -4
  42. package/dist/Deployable/Contract.js.map +1 -1
  43. package/dist/Deployable/Deployable.cjs +1 -1
  44. package/dist/Deployable/Deployable.cjs.map +1 -1
  45. package/dist/Deployable/Deployable.d.ts +7 -0
  46. package/dist/Deployable/Deployable.d.ts.map +1 -1
  47. package/dist/Deployable/Deployable.js +13 -4
  48. package/dist/Deployable/Deployable.js.map +1 -1
  49. package/dist/Deployable/DeployableTarget.cjs +1 -1
  50. package/dist/Deployable/DeployableTarget.js +7 -7
  51. package/dist/Deployable/DeployableTargetWithRBAC.cjs +1 -1
  52. package/dist/Deployable/DeployableTargetWithRBAC.js +16 -16
  53. package/dist/{Incentive-CrnbYN_a.cjs → Incentive-Bse5BKbF.cjs} +2 -2
  54. package/dist/{Incentive-CrnbYN_a.cjs.map → Incentive-Bse5BKbF.cjs.map} +1 -1
  55. package/dist/{Incentive-CeoEla-t.js → Incentive-D1sYPD0W.js} +23 -23
  56. package/dist/{Incentive-CeoEla-t.js.map → Incentive-D1sYPD0W.js.map} +1 -1
  57. package/dist/Incentives/AllowListIncentive.cjs +1 -1
  58. package/dist/Incentives/AllowListIncentive.js +17 -17
  59. package/dist/Incentives/CGDAIncentive.cjs +1 -1
  60. package/dist/Incentives/CGDAIncentive.js +38 -38
  61. package/dist/Incentives/ERC20Incentive.cjs +1 -1
  62. package/dist/Incentives/ERC20Incentive.js +13 -13
  63. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.cjs +1 -1
  64. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.cjs.map +1 -1
  65. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.d.ts +6 -6
  66. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.js +22 -22
  67. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.js.map +1 -1
  68. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.cjs +1 -1
  69. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.cjs.map +1 -1
  70. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.d.ts +6 -6
  71. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.js +91 -91
  72. package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.js.map +1 -1
  73. package/dist/Incentives/ERC20VariableCriteriaIncentive.cjs +1 -1
  74. package/dist/Incentives/ERC20VariableCriteriaIncentive.cjs.map +1 -1
  75. package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts +6 -6
  76. package/dist/Incentives/ERC20VariableCriteriaIncentive.js +9 -9
  77. package/dist/Incentives/ERC20VariableCriteriaIncentive.js.map +1 -1
  78. package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.cjs +1 -1
  79. package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.cjs.map +1 -1
  80. package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.d.ts +6 -6
  81. package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.js +9 -9
  82. package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.js.map +1 -1
  83. package/dist/Incentives/ERC20VariableIncentive.cjs +1 -1
  84. package/dist/Incentives/ERC20VariableIncentive.js +12 -12
  85. package/dist/Incentives/Incentive.cjs +1 -1
  86. package/dist/Incentives/Incentive.js +2 -2
  87. package/dist/Incentives/PointsIncentive.cjs +1 -1
  88. package/dist/Incentives/PointsIncentive.js +10 -10
  89. package/dist/{SimpleDenyList-Dr03aOeP.js → SimpleDenyList-BtEUdiAj.js} +14 -14
  90. package/dist/{SimpleDenyList-Dr03aOeP.js.map → SimpleDenyList-BtEUdiAj.js.map} +1 -1
  91. package/dist/{SimpleDenyList-7-VTqfsH.cjs → SimpleDenyList-DEoMIYhE.cjs} +2 -2
  92. package/dist/{SimpleDenyList-7-VTqfsH.cjs.map → SimpleDenyList-DEoMIYhE.cjs.map} +1 -1
  93. package/dist/{Validator-rYW7PMwW.cjs → Validator-DHS4vjSa.cjs} +2 -2
  94. package/dist/{Validator-rYW7PMwW.cjs.map → Validator-DHS4vjSa.cjs.map} +1 -1
  95. package/dist/{Validator-DgvB9wge.js → Validator-Kpvmj9Bs.js} +9 -9
  96. package/dist/{Validator-DgvB9wge.js.map → Validator-Kpvmj9Bs.js.map} +1 -1
  97. package/dist/Validators/LimitedSignerValidator.cjs +1 -1
  98. package/dist/Validators/LimitedSignerValidator.js +17 -17
  99. package/dist/Validators/SignerValidator.cjs +1 -1
  100. package/dist/Validators/SignerValidator.js +3 -3
  101. package/dist/Validators/Validator.cjs +1 -1
  102. package/dist/Validators/Validator.js +2 -2
  103. package/dist/{deployments-CHQ30INq.js → deployments-Coa8CGi2.js} +67 -67
  104. package/dist/{deployments-CHQ30INq.js.map → deployments-Coa8CGi2.js.map} +1 -1
  105. package/dist/{deployments-BjBgk03b.cjs → deployments-Dgzcz4Ev.cjs} +2 -2
  106. package/dist/deployments-Dgzcz4Ev.cjs.map +1 -0
  107. package/dist/deployments.json +46 -46
  108. package/dist/generated-BzLYuFx3.cjs +3 -0
  109. package/dist/generated-BzLYuFx3.cjs.map +1 -0
  110. package/dist/{generated-B6mEIx8i.js → generated-D6oDILUw.js} +250 -193
  111. package/dist/generated-D6oDILUw.js.map +1 -0
  112. package/dist/index.cjs +1 -1
  113. package/dist/index.js +185 -182
  114. package/dist/utils.cjs.map +1 -1
  115. package/dist/utils.d.ts.map +1 -1
  116. package/dist/utils.js.map +1 -1
  117. package/package.json +1 -1
  118. package/src/Actions/EventAction.test.ts +161 -1
  119. package/src/Actions/EventAction.ts +52 -5
  120. package/src/BoostCore.test.ts +34 -23
  121. package/src/BoostCore.ts +124 -26
  122. package/src/Deployable/Contract.ts +11 -0
  123. package/src/Deployable/Deployable.ts +10 -0
  124. package/src/utils.ts +0 -1
  125. package/dist/deployments-BjBgk03b.cjs.map +0 -1
  126. package/dist/generated-B6mEIx8i.js.map +0 -1
  127. package/dist/generated-dd4FN0Fo.cjs +0 -3
  128. package/dist/generated-dd4FN0Fo.cjs.map +0 -1
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../src/utils.ts"],"sourcesContent":["import { events } from '@boostxyz/signatures';\nimport {\n type Config,\n type ReadContractParameters,\n type SimulateContractParameters,\n type WatchContractEventParameters,\n getAccount,\n getChainId,\n readContract,\n waitForTransactionReceipt,\n} from '@wagmi/core';\nimport type { ExtractAbiEvent } from 'abitype';\nimport type {\n Abi,\n AbiEvent,\n Address,\n ContractEventName,\n ContractFunctionName,\n GetLogsParameters,\n Hash,\n Hex,\n Log,\n WaitForTransactionReceiptParameters,\n} from 'viem';\nimport { isHex, keccak256, slice, toHex } from 'viem';\nimport {\n InvalidProtocolChainIdError,\n NoContractAddressUponReceiptError,\n} from './errors';\n\nexport type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;\n\n/**\n * Enum encapsulating all the different types of targets used in the Boost V2 Protocol.\n *\n * @export\n * @enum {number}\n */\nexport enum RegistryType {\n ACTION = 0,\n ALLOW_LIST = 1,\n BUDGET = 2,\n INCENTIVE = 3,\n VALIDATOR = 4,\n}\n\n/**\n * Enum encapsulating all the different cheat codes for criteria modules.\n * An Event Action action step criteria with a `fieldIndex` set to `CheatCodes.ANY_ACTION_PARAM`, fieldType set to `PrimitiveType.BYTES`, and `filterType` set to `FilterType.EQUAL` will always return true when validating the field, regardless of inputs\n * An Event Action `ActionClaimant` with a `fieldIndex` set to `CheatCodes.TX_SENDER_CLAIMANT`, will always validate with the sender of a given transaction.\n *\n *\n * @export\n * @enum {number}\n */\nexport enum CheatCodes {\n /* An Event Action action step criteria with a `fieldIndex` set to `CheatCodes.ANY_ACTION_PARAM`, fieldType set to `PrimitiveType.BYTES`, and `filterType` set to `FilterType.EQUAL` will always return true when validating the field, regardless of inputs */\n ANY_ACTION_PARAM = 255,\n /* An Event Action `ActionClaimant` with a `fieldIndex` set to `CheatCodes.TX_SENDER_CLAIMANT`, will always validate with the sender of a given transaction. */\n TX_SENDER_CLAIMANT = 255,\n /* For use with `ERC20VariableCriteriaIncentiveV2`, if the criteria's `fieldIndex` is set to `CheatCodes.GAS_REBATE_INCENTIVE`, will claim an incentive amount equal to the transaction's gas used. */\n GAS_REBATE_INCENTIVE = 255,\n}\n\n/**\n * The signature for the Transfer event for both ERC20 and ERC721.\n *\n * @type {Hex}\n */\nexport const TRANSFER_SIGNATURE = events.selectors[\n 'Transfer(address indexed,address indexed,uint256 indexed)'\n] as Hex;\n\n/**\n * Helper type that encapsulates common writeContract parameters without fields like `abi`, `args`, `functionName`, `address` that are expected to be provided the SDK.\n * See (writeContract)[https://viem.sh/docs/contract/writeContract]\n *\n * @export\n * @typedef {WriteParams}\n * @template {Abi} abi\n * @template {ContractFunctionName<abi>} functionName\n */\nexport type WriteParams = Partial<\n Omit<SimulateContractParameters, 'address' | 'args' | 'functionName' | 'abi'>\n>;\n\n/**\n * Helper type that encapsulates common readContract parameters without fields like `abi`, `args`, `functionName`, `address` that are expected to be provided the SDK.\n * See (readContract)[https://viem.sh/docs/contract/readContract]\n *\n * @export\n * @typedef {ReadParams}\n * @template {Abi} abi\n * @template {ContractFunctionName<abi>} functionName\n */\nexport type ReadParams = Partial<\n Omit<ReadContractParameters, 'address' | 'args' | 'functionName' | 'abi'>\n>;\n\n/**\n * Helper type that encapsulates common `watchContractEvent` parameters without fields like `address`, and `abi` that are expected to be provided the SDK.\n * See (watchContractEvent)[https://wagmi.sh/core/api/actions/watchContractEvent]\n *\n * @export\n * @typedef {WatchParams}\n * @template {Abi} abi\n * @template {ContractEventName<abi> | undefined} [eventName=undefined]\n */\nexport type WatchParams<\n abi extends Abi,\n eventName extends ContractEventName<abi> | undefined = undefined,\n> = Partial<\n Omit<WatchContractEventParameters<abi, eventName>, 'address' | 'abi'>\n>;\n\n/**\n * Helper type that encapsulates common `getLogs` parameters without fields like `address` that are expected to be provided the SDK.\n * See (getLogs)[https://viem.sh/docs/actions/public/getLogs#getlogs]\n *\n * @export\n * @typedef {GetLogsParams}\n * @template {Abi} abi\n * @template {ContractEventName<abi>} event\n * @template {ExtractAbiEvent<abi, event>} [abiEvent=ExtractAbiEvent<abi, event>]\n * @template {| readonly AbiEvent[]\n * | readonly unknown[]\n * | undefined} [abiEvents=abiEvent extends AbiEvent ? [abiEvent] : undefined]\n */\nexport type GetLogsParams<\n abi extends Abi,\n event extends ContractEventName<abi>,\n abiEvent extends ExtractAbiEvent<abi, event> = ExtractAbiEvent<abi, event>,\n abiEvents extends\n | readonly AbiEvent[]\n | readonly unknown[]\n | undefined = abiEvent extends AbiEvent ? [abiEvent] : undefined,\n> = Partial<Omit<GetLogsParameters<abiEvent, abiEvents>, 'address'>> & {\n chainId?: number | undefined;\n};\n\n/**\n * A generic `viem.Log` event with typed `args` support via a given `Abi` and `ContractEventName`\n *\n * @export\n * @typedef {GenericLog}\n * @template {Abi} abi\n * @template {ContractEventName<abi>} [event=ContractEventName<abi>]\n */\nexport type GenericLog<\n abi extends Abi,\n event extends ContractEventName<abi> = ContractEventName<abi>,\n> = Log<bigint, number, false, ExtractAbiEvent<abi, event>, false>;\n\n/**\n * Helper utility to convert a string to a `bytes4` type\n *\n * @export\n * @param {string} input\n * @returns {Hex}\n */\nexport function bytes4(input: string) {\n return slice(isHex(input) ? keccak256(input) : keccak256(toHex(input)), 0, 4);\n}\n\n/**\n * Utility function to wait for a transaction receipt, and extract the contractAddress\n *\n * @export\n * @async\n * @param {WagmiConfig} config - [Wagmi Configuration](https://wagmi.sh/core/api/createConfig)\n * @param {Promise<Hash>} hash - A transaction hash promise\n * @param {?Omit<WaitForTransactionReceiptParameters, 'hash'>} [waitParams] - @see {@link WaitForTransactionReceiptParameters}\n * @returns {Promise<Address>}\n * @throws {@link NoContractAddressUponReceiptError} if no `contractAddress` exists after the transaction has been received\n */\nexport async function getDeployedContractAddress(\n config: Config,\n hash: Promise<Hash>,\n waitParams?: Omit<WaitForTransactionReceiptParameters, 'hash'>,\n) {\n const receipt = await waitForTransactionReceipt(config, {\n ...waitParams,\n hash: await hash,\n });\n if (!receipt.contractAddress)\n throw new NoContractAddressUponReceiptError(receipt);\n return receipt.contractAddress;\n}\n\n/**\n * Utility type to encapsulate a transaction hash, and the simulated result prior to submitting the transaction.\n *\n * @export\n * @typedef {HashAndSimulatedResult}\n * @template [T=unknown]\n */\nexport type HashAndSimulatedResult<T = unknown> = { hash: Hash; result: T };\n\n/**\n * Helper function to wait for a transaction receipt given a hash promise.\n *\n * @export\n * @async\n * @template [Result=unknown]\n * @param {WagmiConfig} config\n * @param {Promise<HashAndSimulatedResult<Result>>} hashPromise\n * @param {?Omit<WaitForTransactionReceiptParameters, 'hash'>} [waitParams]\n * @returns {Promise<Result>}\n */\nexport async function awaitResult<Result = unknown>(\n config: Config,\n hashPromise: Promise<HashAndSimulatedResult<Result>>,\n waitParams?: Omit<WaitForTransactionReceiptParameters, 'hash'>,\n): Promise<Result> {\n const { hash, result } = await hashPromise;\n await waitForTransactionReceipt(config, {\n ...waitParams,\n hash,\n });\n return result;\n}\n\n/**\n * Given a wagmi config and a map of chain id's to addresses, determine an address/chainId combo that maps to the currently connected chain id, or throw a typed error.\n *\n * @export\n * @param {Config} config\n * @param {Record<string, Address>} addressByChainId\n * @param {number} desiredChainId\n * @returns {{ chainId: number, address: Address }}\n * @throws {@link InvalidProtocolChainIdError}\n */\nexport function assertValidAddressByChainId(\n config: Config,\n addressByChainId: Record<number, Address>,\n desiredChainId?: number,\n): { chainId: number; address: Address } {\n let chainId: number | undefined = undefined;\n\n const wagmiChainId = getChainId(config);\n if (wagmiChainId && addressByChainId[wagmiChainId]) chainId = wagmiChainId;\n // if manually providing a chain id for some contract operation, try to use it\n if (desiredChainId !== undefined) {\n if (addressByChainId[desiredChainId]) chainId = desiredChainId;\n } else if (wagmiChainId !== undefined) {\n // otherwise if we can get the current chain id off the connected account and it matches one of ours, use it\n if (addressByChainId[wagmiChainId]) chainId = wagmiChainId;\n }\n // chainId is still undefined, try to get chain id off viem client\n if (chainId === undefined) {\n const wagmiAccount = getAccount(config);\n if (wagmiAccount.chainId !== undefined) {\n // otherwise if we can get the current chain id off the connected account and it matches one of ours, use it\n if (addressByChainId[wagmiAccount.chainId])\n chainId = wagmiAccount.chainId;\n }\n }\n // if chainId is STILL undefined, use our default addresses\n // TODO: update this when on prod network\n if (chainId === undefined) chainId = Number(__DEFAULT_CHAIN_ID__);\n if (!addressByChainId[chainId])\n throw new InvalidProtocolChainIdError(\n chainId,\n Object.keys(addressByChainId).map(Number),\n );\n // biome-ignore lint/style/noNonNullAssertion: this type should be narrowed by the above statement but isn't?\n return { chainId, address: addressByChainId[chainId]! };\n}\n\n/**\n * Check an ERC20's balance for a given asset and\n *\n * @public\n * @async\n * @param {Config} [config]\n * @param {Address} [asset]\n * @param {Address} [owner]\n * @param {?ReadParams} [params]\n * @returns {Promise<bigint>} - The erc20 balance\n */\nexport async function getErc20Balance(\n config: Config,\n asset: Address,\n owner: Address,\n params?: ReadParams,\n) {\n return await readContract(config, {\n ...params,\n functionName: 'balanceOf',\n address: asset,\n args: [owner],\n abi: [\n {\n constant: true,\n inputs: [\n {\n name: '_owner',\n type: 'address',\n },\n ],\n name: 'balanceOf',\n outputs: [\n {\n name: 'balance',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n ],\n });\n}\n"],"names":["RegistryType","CheatCodes","TRANSFER_SIGNATURE","events","bytes4","input","slice","isHex","keccak256","toHex","getDeployedContractAddress","config","hash","waitParams","receipt","waitForTransactionReceipt","NoContractAddressUponReceiptError","awaitResult","hashPromise","result","assertValidAddressByChainId","addressByChainId","desiredChainId","chainId","wagmiChainId","getChainId","wagmiAccount","getAccount","InvalidProtocolChainIdError","getErc20Balance","asset","owner","params","readContract"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
1
+ {"version":3,"file":"utils.js","sources":["../src/utils.ts"],"sourcesContent":["import { events } from '@boostxyz/signatures';\nimport {\n type Config,\n type ReadContractParameters,\n type SimulateContractParameters,\n type WatchContractEventParameters,\n getAccount,\n getChainId,\n readContract,\n waitForTransactionReceipt,\n} from '@wagmi/core';\nimport type { ExtractAbiEvent } from 'abitype';\nimport type {\n Abi,\n AbiEvent,\n Address,\n ContractEventName,\n GetLogsParameters,\n Hash,\n Hex,\n Log,\n WaitForTransactionReceiptParameters,\n} from 'viem';\nimport { isHex, keccak256, slice, toHex } from 'viem';\nimport {\n InvalidProtocolChainIdError,\n NoContractAddressUponReceiptError,\n} from './errors';\n\nexport type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;\n\n/**\n * Enum encapsulating all the different types of targets used in the Boost V2 Protocol.\n *\n * @export\n * @enum {number}\n */\nexport enum RegistryType {\n ACTION = 0,\n ALLOW_LIST = 1,\n BUDGET = 2,\n INCENTIVE = 3,\n VALIDATOR = 4,\n}\n\n/**\n * Enum encapsulating all the different cheat codes for criteria modules.\n * An Event Action action step criteria with a `fieldIndex` set to `CheatCodes.ANY_ACTION_PARAM`, fieldType set to `PrimitiveType.BYTES`, and `filterType` set to `FilterType.EQUAL` will always return true when validating the field, regardless of inputs\n * An Event Action `ActionClaimant` with a `fieldIndex` set to `CheatCodes.TX_SENDER_CLAIMANT`, will always validate with the sender of a given transaction.\n *\n *\n * @export\n * @enum {number}\n */\nexport enum CheatCodes {\n /* An Event Action action step criteria with a `fieldIndex` set to `CheatCodes.ANY_ACTION_PARAM`, fieldType set to `PrimitiveType.BYTES`, and `filterType` set to `FilterType.EQUAL` will always return true when validating the field, regardless of inputs */\n ANY_ACTION_PARAM = 255,\n /* An Event Action `ActionClaimant` with a `fieldIndex` set to `CheatCodes.TX_SENDER_CLAIMANT`, will always validate with the sender of a given transaction. */\n TX_SENDER_CLAIMANT = 255,\n /* For use with `ERC20VariableCriteriaIncentiveV2`, if the criteria's `fieldIndex` is set to `CheatCodes.GAS_REBATE_INCENTIVE`, will claim an incentive amount equal to the transaction's gas used. */\n GAS_REBATE_INCENTIVE = 255,\n}\n\n/**\n * The signature for the Transfer event for both ERC20 and ERC721.\n *\n * @type {Hex}\n */\nexport const TRANSFER_SIGNATURE = events.selectors[\n 'Transfer(address indexed,address indexed,uint256 indexed)'\n] as Hex;\n\n/**\n * Helper type that encapsulates common writeContract parameters without fields like `abi`, `args`, `functionName`, `address` that are expected to be provided the SDK.\n * See (writeContract)[https://viem.sh/docs/contract/writeContract]\n *\n * @export\n * @typedef {WriteParams}\n * @template {Abi} abi\n * @template {ContractFunctionName<abi>} functionName\n */\nexport type WriteParams = Partial<\n Omit<SimulateContractParameters, 'address' | 'args' | 'functionName' | 'abi'>\n>;\n\n/**\n * Helper type that encapsulates common readContract parameters without fields like `abi`, `args`, `functionName`, `address` that are expected to be provided the SDK.\n * See (readContract)[https://viem.sh/docs/contract/readContract]\n *\n * @export\n * @typedef {ReadParams}\n * @template {Abi} abi\n * @template {ContractFunctionName<abi>} functionName\n */\nexport type ReadParams = Partial<\n Omit<ReadContractParameters, 'address' | 'args' | 'functionName' | 'abi'>\n>;\n\n/**\n * Helper type that encapsulates common `watchContractEvent` parameters without fields like `address`, and `abi` that are expected to be provided the SDK.\n * See (watchContractEvent)[https://wagmi.sh/core/api/actions/watchContractEvent]\n *\n * @export\n * @typedef {WatchParams}\n * @template {Abi} abi\n * @template {ContractEventName<abi> | undefined} [eventName=undefined]\n */\nexport type WatchParams<\n abi extends Abi,\n eventName extends ContractEventName<abi> | undefined = undefined,\n> = Partial<\n Omit<WatchContractEventParameters<abi, eventName>, 'address' | 'abi'>\n>;\n\n/**\n * Helper type that encapsulates common `getLogs` parameters without fields like `address` that are expected to be provided the SDK.\n * See (getLogs)[https://viem.sh/docs/actions/public/getLogs#getlogs]\n *\n * @export\n * @typedef {GetLogsParams}\n * @template {Abi} abi\n * @template {ContractEventName<abi>} event\n * @template {ExtractAbiEvent<abi, event>} [abiEvent=ExtractAbiEvent<abi, event>]\n * @template {| readonly AbiEvent[]\n * | readonly unknown[]\n * | undefined} [abiEvents=abiEvent extends AbiEvent ? [abiEvent] : undefined]\n */\nexport type GetLogsParams<\n abi extends Abi,\n event extends ContractEventName<abi>,\n abiEvent extends ExtractAbiEvent<abi, event> = ExtractAbiEvent<abi, event>,\n abiEvents extends\n | readonly AbiEvent[]\n | readonly unknown[]\n | undefined = abiEvent extends AbiEvent ? [abiEvent] : undefined,\n> = Partial<Omit<GetLogsParameters<abiEvent, abiEvents>, 'address'>> & {\n chainId?: number | undefined;\n};\n\n/**\n * A generic `viem.Log` event with typed `args` support via a given `Abi` and `ContractEventName`\n *\n * @export\n * @typedef {GenericLog}\n * @template {Abi} abi\n * @template {ContractEventName<abi>} [event=ContractEventName<abi>]\n */\nexport type GenericLog<\n abi extends Abi,\n event extends ContractEventName<abi> = ContractEventName<abi>,\n> = Log<bigint, number, false, ExtractAbiEvent<abi, event>, false>;\n\n/**\n * Helper utility to convert a string to a `bytes4` type\n *\n * @export\n * @param {string} input\n * @returns {Hex}\n */\nexport function bytes4(input: string) {\n return slice(isHex(input) ? keccak256(input) : keccak256(toHex(input)), 0, 4);\n}\n\n/**\n * Utility function to wait for a transaction receipt, and extract the contractAddress\n *\n * @export\n * @async\n * @param {WagmiConfig} config - [Wagmi Configuration](https://wagmi.sh/core/api/createConfig)\n * @param {Promise<Hash>} hash - A transaction hash promise\n * @param {?Omit<WaitForTransactionReceiptParameters, 'hash'>} [waitParams] - @see {@link WaitForTransactionReceiptParameters}\n * @returns {Promise<Address>}\n * @throws {@link NoContractAddressUponReceiptError} if no `contractAddress` exists after the transaction has been received\n */\nexport async function getDeployedContractAddress(\n config: Config,\n hash: Promise<Hash>,\n waitParams?: Omit<WaitForTransactionReceiptParameters, 'hash'>,\n) {\n const receipt = await waitForTransactionReceipt(config, {\n ...waitParams,\n hash: await hash,\n });\n if (!receipt.contractAddress)\n throw new NoContractAddressUponReceiptError(receipt);\n return receipt.contractAddress;\n}\n\n/**\n * Utility type to encapsulate a transaction hash, and the simulated result prior to submitting the transaction.\n *\n * @export\n * @typedef {HashAndSimulatedResult}\n * @template [T=unknown]\n */\nexport type HashAndSimulatedResult<T = unknown> = { hash: Hash; result: T };\n\n/**\n * Helper function to wait for a transaction receipt given a hash promise.\n *\n * @export\n * @async\n * @template [Result=unknown]\n * @param {WagmiConfig} config\n * @param {Promise<HashAndSimulatedResult<Result>>} hashPromise\n * @param {?Omit<WaitForTransactionReceiptParameters, 'hash'>} [waitParams]\n * @returns {Promise<Result>}\n */\nexport async function awaitResult<Result = unknown>(\n config: Config,\n hashPromise: Promise<HashAndSimulatedResult<Result>>,\n waitParams?: Omit<WaitForTransactionReceiptParameters, 'hash'>,\n): Promise<Result> {\n const { hash, result } = await hashPromise;\n await waitForTransactionReceipt(config, {\n ...waitParams,\n hash,\n });\n return result;\n}\n\n/**\n * Given a wagmi config and a map of chain id's to addresses, determine an address/chainId combo that maps to the currently connected chain id, or throw a typed error.\n *\n * @export\n * @param {Config} config\n * @param {Record<string, Address>} addressByChainId\n * @param {number} desiredChainId\n * @returns {{ chainId: number, address: Address }}\n * @throws {@link InvalidProtocolChainIdError}\n */\nexport function assertValidAddressByChainId(\n config: Config,\n addressByChainId: Record<number, Address>,\n desiredChainId?: number,\n): { chainId: number; address: Address } {\n let chainId: number | undefined = undefined;\n\n const wagmiChainId = getChainId(config);\n if (wagmiChainId && addressByChainId[wagmiChainId]) chainId = wagmiChainId;\n // if manually providing a chain id for some contract operation, try to use it\n if (desiredChainId !== undefined) {\n if (addressByChainId[desiredChainId]) chainId = desiredChainId;\n } else if (wagmiChainId !== undefined) {\n // otherwise if we can get the current chain id off the connected account and it matches one of ours, use it\n if (addressByChainId[wagmiChainId]) chainId = wagmiChainId;\n }\n // chainId is still undefined, try to get chain id off viem client\n if (chainId === undefined) {\n const wagmiAccount = getAccount(config);\n if (wagmiAccount.chainId !== undefined) {\n // otherwise if we can get the current chain id off the connected account and it matches one of ours, use it\n if (addressByChainId[wagmiAccount.chainId])\n chainId = wagmiAccount.chainId;\n }\n }\n // if chainId is STILL undefined, use our default addresses\n // TODO: update this when on prod network\n if (chainId === undefined) chainId = Number(__DEFAULT_CHAIN_ID__);\n if (!addressByChainId[chainId])\n throw new InvalidProtocolChainIdError(\n chainId,\n Object.keys(addressByChainId).map(Number),\n );\n // biome-ignore lint/style/noNonNullAssertion: this type should be narrowed by the above statement but isn't?\n return { chainId, address: addressByChainId[chainId]! };\n}\n\n/**\n * Check an ERC20's balance for a given asset and\n *\n * @public\n * @async\n * @param {Config} [config]\n * @param {Address} [asset]\n * @param {Address} [owner]\n * @param {?ReadParams} [params]\n * @returns {Promise<bigint>} - The erc20 balance\n */\nexport async function getErc20Balance(\n config: Config,\n asset: Address,\n owner: Address,\n params?: ReadParams,\n) {\n return await readContract(config, {\n ...params,\n functionName: 'balanceOf',\n address: asset,\n args: [owner],\n abi: [\n {\n constant: true,\n inputs: [\n {\n name: '_owner',\n type: 'address',\n },\n ],\n name: 'balanceOf',\n outputs: [\n {\n name: 'balance',\n type: 'uint256',\n },\n ],\n stateMutability: 'view',\n type: 'function',\n },\n ],\n });\n}\n"],"names":["RegistryType","CheatCodes","TRANSFER_SIGNATURE","events","bytes4","input","slice","isHex","keccak256","toHex","getDeployedContractAddress","config","hash","waitParams","receipt","waitForTransactionReceipt","NoContractAddressUponReceiptError","awaitResult","hashPromise","result","assertValidAddressByChainId","addressByChainId","desiredChainId","chainId","wagmiChainId","getChainId","wagmiAccount","getAccount","InvalidProtocolChainIdError","getErc20Balance","asset","owner","params","readContract"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCY,IAAAA,sBAAAA,OACVA,EAAAA,EAAA,SAAS,CAAT,IAAA,UACAA,EAAAA,EAAA,aAAa,CAAb,IAAA,cACAA,EAAAA,EAAA,SAAS,CAAT,IAAA,UACAA,EAAAA,EAAA,YAAY,CAAZ,IAAA,aACAA,EAAAA,EAAA,YAAY,CAAZ,IAAA,aALUA,IAAAA,KAAA,CAAA,CAAA,GAiBAC,sBAAAA,OAEVA,EAAAA,EAAA,mBAAmB,GAAnB,IAAA,oBAEAA,EAAAA,EAAA,qBAAqB,GAArB,IAAA,sBAEAA,EAAAA,EAAA,uBAAuB,GAAvB,IAAA,wBANUA,IAAAA,KAAA,CAAA,CAAA;AAcC,MAAAC,IAAqBC,EAAO,UACvC,2DACF;AAyFO,SAASC,EAAOC,GAAe;AACpC,SAAOC,EAAMC,EAAMF,CAAK,IAAIG,EAAUH,CAAK,IAAIG,EAAUC,EAAMJ,CAAK,CAAC,GAAG,GAAG,CAAC;AAC9E;AAasB,eAAAK,EACpBC,GACAC,GACAC,GACA;AACM,QAAAC,IAAU,MAAMC,EAA0BJ,GAAQ;AAAA,IACtD,GAAGE;AAAA,IACH,MAAM,MAAMD;AAAA,EAAA,CACb;AACD,MAAI,CAACE,EAAQ;AACL,UAAA,IAAIE,EAAkCF,CAAO;AACrD,SAAOA,EAAQ;AACjB;AAsBsB,eAAAG,EACpBN,GACAO,GACAL,GACiB;AACjB,QAAM,EAAE,MAAAD,GAAM,QAAAO,EAAO,IAAI,MAAMD;AAC/B,eAAMH,EAA0BJ,GAAQ;AAAA,IACtC,GAAGE;AAAA,IACH,MAAAD;AAAA,EAAA,CACD,GACMO;AACT;AAYgB,SAAAC,EACdT,GACAU,GACAC,GACuC;AACvC,MAAIC;AAEE,QAAAC,IAAeC,EAAWd,CAAM;AAUtC,MATIa,KAAgBH,EAAiBG,CAAY,MAAaD,IAAAC,IAE1DF,MAAmB,SACjBD,EAAiBC,CAAc,MAAaC,IAAAD,KACvCE,MAAiB,UAEtBH,EAAiBG,CAAY,MAAaD,IAAAC,IAG5CD,MAAY,QAAW;AACnB,UAAAG,IAAeC,EAAWhB,CAAM;AAClC,IAAAe,EAAa,YAAY,UAEvBL,EAAiBK,EAAa,OAAO,MACvCH,IAAUG,EAAa;AAAA,EAE7B;AAII,MADAH,MAAY,WAAqBA,IAAO,WACxC,CAACF,EAAiBE,CAAO;AAC3B,UAAM,IAAIK;AAAA,MACRL;AAAA,MACA,OAAO,KAAKF,CAAgB,EAAE,IAAI,MAAM;AAAA,IAAA;AAG5C,SAAO,EAAE,SAAAE,GAAS,SAASF,EAAiBE,CAAO,EAAG;AACxD;AAaA,eAAsBM,EACpBlB,GACAmB,GACAC,GACAC,GACA;AACO,SAAA,MAAMC,EAAatB,GAAQ;AAAA,IAChC,GAAGqB;AAAA,IACH,cAAc;AAAA,IACd,SAASF;AAAA,IACT,MAAM,CAACC,CAAK;AAAA,IACZ,KAAK;AAAA,MACH;AAAA,QACE,UAAU;AAAA,QACV,QAAQ;AAAA,UACN;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,UACR;AAAA,QACF;AAAA,QACA,MAAM;AAAA,QACN,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,UACR;AAAA,QACF;AAAA,QACA,iBAAiB;AAAA,QACjB,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EAAA,CACD;AACH;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boostxyz/sdk",
3
- "version": "7.7.0",
3
+ "version": "8.0.0-canary.0",
4
4
  "license": "GPL-3.0-or-later",
5
5
  "type": "module",
6
6
  "files": [
@@ -44,7 +44,9 @@ import {
44
44
  packCriteriaFieldIndexes,
45
45
  unpackCriteriaFieldIndexes,
46
46
  isCriteriaFieldIndexTuple,
47
- decodeAndReorderLogArgs
47
+ packClaimantFieldIndexes,
48
+ decodeAndReorderLogArgs,
49
+ ActionClaimant
48
50
  } from "./EventAction";
49
51
  import { allKnownSignatures } from "@boostxyz/test/allKnownSignatures";
50
52
  import { getTransactionReceipt } from "@wagmi/core";
@@ -1602,3 +1604,161 @@ describe("criteria field index tuple support", () => {
1602
1604
  });
1603
1605
  });
1604
1606
  });
1607
+
1608
+ describe("claimant tuple field support", () => {
1609
+ describe("validateClaimantAgainstArgs with tuple access", () => {
1610
+ test("correctly extracts address from tuple field", () => {
1611
+ const eventAction = new EventAction({ config: {} as any });
1612
+
1613
+ // Test args with a tuple containing an address at position [2][1]
1614
+ const testArgs = [
1615
+ "0x1111111111111111111111111111111111111111",
1616
+ 100n,
1617
+ ["0x2222222222222222222222222222222222222222", "0x3333333333333333333333333333333333333333", 500n],
1618
+ "test"
1619
+ ];
1620
+
1621
+ // Test extracting from tuple at args[2][1]
1622
+ const claimant: ActionClaimant = {
1623
+ signatureType: SignatureType.EVENT,
1624
+ signature: zeroHash,
1625
+ fieldIndex: packClaimantFieldIndexes([2, 1]),
1626
+ targetContract: zeroAddress,
1627
+ chainid: 1
1628
+ };
1629
+
1630
+ const result = eventAction.validateClaimantAgainstArgs(claimant, { args: testArgs });
1631
+ expect(result).toBe("0x3333333333333333333333333333333333333333");
1632
+ });
1633
+
1634
+ test("returns undefined if tuple index is out of bounds", () => {
1635
+ const eventAction = new EventAction({ config: {} as any });
1636
+
1637
+ const testArgs = [
1638
+ "0x1111111111111111111111111111111111111111",
1639
+ ["0x2222222222222222222222222222222222222222"]
1640
+ ];
1641
+
1642
+ // Try to access args[1][2] which doesn't exist
1643
+ const claimant: ActionClaimant = {
1644
+ signatureType: SignatureType.EVENT,
1645
+ signature: zeroHash,
1646
+ fieldIndex: packClaimantFieldIndexes([1, 2]),
1647
+ targetContract: zeroAddress,
1648
+ chainid: 1
1649
+ };
1650
+
1651
+ const result = eventAction.validateClaimantAgainstArgs(claimant, { args: testArgs });
1652
+ expect(result).toBeUndefined();
1653
+ });
1654
+
1655
+ test("returns undefined if first index is out of bounds", () => {
1656
+ const eventAction = new EventAction({ config: {} as any });
1657
+
1658
+ const testArgs = ["0x1111111111111111111111111111111111111111"];
1659
+
1660
+ // Try to access args[5][0] where args[5] doesn't exist
1661
+ const claimant: ActionClaimant = {
1662
+ signatureType: SignatureType.EVENT,
1663
+ signature: zeroHash,
1664
+ fieldIndex: packClaimantFieldIndexes([5, 0]),
1665
+ targetContract: zeroAddress,
1666
+ chainid: 1
1667
+ };
1668
+
1669
+ const result = eventAction.validateClaimantAgainstArgs(claimant, { args: testArgs });
1670
+ expect(result).toBeUndefined();
1671
+ });
1672
+
1673
+ test("returns undefined if tuple field is not an address", () => {
1674
+ const eventAction = new EventAction({ config: {} as any });
1675
+
1676
+ const testArgs = [
1677
+ ["not-an-address", 123n, "test"]
1678
+ ];
1679
+
1680
+ // Try to access args[0][0] which is not an address
1681
+ const claimant: ActionClaimant = {
1682
+ signatureType: SignatureType.EVENT,
1683
+ signature: zeroHash,
1684
+ fieldIndex: packClaimantFieldIndexes([0, 0]),
1685
+ targetContract: zeroAddress,
1686
+ chainid: 1
1687
+ };
1688
+
1689
+ const result = eventAction.validateClaimantAgainstArgs(claimant, { args: testArgs });
1690
+ expect(result).toBeUndefined();
1691
+ });
1692
+
1693
+ test("returns undefined if field at first index is not a tuple", () => {
1694
+ const eventAction = new EventAction({ config: {} as any });
1695
+
1696
+ const testArgs = [
1697
+ "0x1111111111111111111111111111111111111111",
1698
+ "not-a-tuple"
1699
+ ];
1700
+
1701
+ // Try to access args[1][0] but args[1] is not an array
1702
+ const claimant: ActionClaimant = {
1703
+ signatureType: SignatureType.EVENT,
1704
+ signature: zeroHash,
1705
+ fieldIndex: packClaimantFieldIndexes([1, 0]),
1706
+ targetContract: zeroAddress,
1707
+ chainid: 1
1708
+ };
1709
+
1710
+ const result = eventAction.validateClaimantAgainstArgs(claimant, { args: testArgs });
1711
+ expect(result).toBeUndefined();
1712
+ });
1713
+
1714
+ test("still handles direct field access correctly", () => {
1715
+ const eventAction = new EventAction({ config: {} as any });
1716
+
1717
+ const testArgs = [
1718
+ "0x1111111111111111111111111111111111111111",
1719
+ "0x2222222222222222222222222222222222222222",
1720
+ 100n
1721
+ ];
1722
+
1723
+ // Direct access to args[1] (not a tuple index)
1724
+ const claimant: ActionClaimant = {
1725
+ signatureType: SignatureType.EVENT,
1726
+ signature: zeroHash,
1727
+ fieldIndex: 1,
1728
+ targetContract: zeroAddress,
1729
+ chainid: 1
1730
+ };
1731
+
1732
+ const result = eventAction.validateClaimantAgainstArgs(claimant, { args: testArgs });
1733
+ expect(result).toBe("0x2222222222222222222222222222222222222222");
1734
+ });
1735
+
1736
+ test("handles complex tuple with correct address", () => {
1737
+ const eventAction = new EventAction({ config: {} as any });
1738
+
1739
+ // Complex nested structure
1740
+ const testArgs = [
1741
+ { someField: "data" },
1742
+ 100n,
1743
+ [
1744
+ "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
1745
+ "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
1746
+ ["nested", "data"],
1747
+ "0xcccccccccccccccccccccccccccccccccccccccc"
1748
+ ]
1749
+ ];
1750
+
1751
+ // Access args[2][3] which is an address
1752
+ const claimant: ActionClaimant = {
1753
+ signatureType: SignatureType.EVENT,
1754
+ signature: zeroHash,
1755
+ fieldIndex: packClaimantFieldIndexes([2, 3]),
1756
+ targetContract: zeroAddress,
1757
+ chainid: 1
1758
+ };
1759
+
1760
+ const result = eventAction.validateClaimantAgainstArgs(claimant, { args: testArgs });
1761
+ expect(result).toBe("0xcccccccccccccccccccccccccccccccccccccccc");
1762
+ });
1763
+ });
1764
+ });
@@ -671,11 +671,28 @@ export class EventAction extends DeployableTarget<
671
671
  args: Array<unknown> | readonly unknown[] | Record<string, unknown>;
672
672
  },
673
673
  ): Address | undefined {
674
- if (
675
- !logOrFnData ||
676
- !Array.isArray(logOrFnData?.args) ||
677
- logOrFnData?.args.length <= claimant.fieldIndex
678
- ) {
674
+ if (!logOrFnData || !Array.isArray(logOrFnData?.args)) {
675
+ return;
676
+ }
677
+
678
+ if (isClaimantFieldIndexTuple(claimant.fieldIndex)) {
679
+ const [index0, index1] = unpackClaimantFieldIndexes(claimant.fieldIndex);
680
+
681
+ if (logOrFnData.args.length <= index0) {
682
+ return;
683
+ }
684
+
685
+ const tuple = logOrFnData.args[index0];
686
+ if (!Array.isArray(tuple) || tuple.length <= index1) {
687
+ return;
688
+ }
689
+
690
+ const maybeAddress = tuple[index1];
691
+ if (isAddress(maybeAddress)) return maybeAddress;
692
+ return;
693
+ }
694
+
695
+ if (logOrFnData.args.length <= claimant.fieldIndex) {
679
696
  return;
680
697
  }
681
698
  const maybeAddress = logOrFnData.args.at(claimant.fieldIndex);
@@ -1990,6 +2007,36 @@ export function isCriteriaFieldIndexTuple(fieldIndex: number): boolean {
1990
2007
  return fieldIndex >= 32;
1991
2008
  }
1992
2009
 
2010
+ /**
2011
+ * Helper function to check if a claimant fieldIndex represents tuple access.
2012
+ *
2013
+ * @param {number} fieldIndex - The field index to check
2014
+ * @returns {boolean} - True if it's a tuple index, false for direct access
2015
+ */
2016
+ export function isClaimantFieldIndexTuple(fieldIndex: number): boolean {
2017
+ return isCriteriaFieldIndexTuple(fieldIndex);
2018
+ }
2019
+
2020
+ /**
2021
+ * Packs two indices for claimant tuple access.
2022
+ *
2023
+ * @param {[number, number]} indices - Tuple of [firstIndex, secondIndex]
2024
+ * @returns {number} - Packed uint8 value for the claimant fieldIndex
2025
+ */
2026
+ export function packClaimantFieldIndexes(indices: [number, number]): number {
2027
+ return packCriteriaFieldIndexes(indices);
2028
+ }
2029
+
2030
+ /**
2031
+ * Unpacks a claimant fieldIndex into tuple indices.
2032
+ *
2033
+ * @param {number} packed - Packed fieldIndex value
2034
+ * @returns {[number, number]} - [firstIndex, secondIndex]
2035
+ */
2036
+ export function unpackClaimantFieldIndexes(packed: number): [number, number] {
2037
+ return unpackCriteriaFieldIndexes(packed);
2038
+ }
2039
+
1993
2040
  /**
1994
2041
  * Extracts a scalar value from a tuple within event or function arguments.
1995
2042
  * This is used for incentive criteria when determining reward amounts.
@@ -77,6 +77,7 @@ describe("BoostCore", () => {
77
77
  await core.getBoost(1000n);
78
78
  } catch (e) {
79
79
  expect(e instanceof BoostNotFoundError).toBe(true);
80
+ // @ts-ignore
80
81
  expect(e.id).toBe("1000");
81
82
  }
82
83
  });
@@ -648,20 +649,20 @@ describe("BoostCore", () => {
648
649
  // expect(erc721MintAction._account).toEqual(defaultOptions.account);
649
650
 
650
651
  const eventAction = core.EventAction(zeroAddress);
651
- expect(eventAction._config).toEqual(defaultOptions.config);
652
- expect(eventAction._account).toEqual(defaultOptions.account);
652
+ expect(eventAction.config).toEqual(defaultOptions.config);
653
+ expect(eventAction.account).toEqual(defaultOptions.account);
653
654
 
654
655
  const allowList = core.SimpleAllowList(zeroAddress);
655
- expect(allowList._config).toEqual(defaultOptions.config);
656
- expect(allowList._account).toEqual(defaultOptions.account);
656
+ expect(allowList.config).toEqual(defaultOptions.config);
657
+ expect(allowList.account).toEqual(defaultOptions.account);
657
658
 
658
659
  const denyList = core.SimpleDenyList(zeroAddress);
659
- expect(denyList._config).toEqual(defaultOptions.config);
660
- expect(denyList._account).toEqual(defaultOptions.account);
660
+ expect(denyList.config).toEqual(defaultOptions.config);
661
+ expect(denyList.account).toEqual(defaultOptions.account);
661
662
 
662
663
  const managedBudget = core.ManagedBudget(zeroAddress);
663
- expect(managedBudget._config).toEqual(defaultOptions.config);
664
- expect(managedBudget._account).toEqual(defaultOptions.account);
664
+ expect(managedBudget.config).toEqual(defaultOptions.config);
665
+ expect(managedBudget.account).toEqual(defaultOptions.account);
665
666
 
666
667
  // const simpleBudget = core.SimpleBudget(zeroAddress);
667
668
  // expect(simpleBudget._config).toEqual(defaultOptions.config);
@@ -675,8 +676,8 @@ describe("BoostCore", () => {
675
676
  allowList: zeroAddress,
676
677
  limit: 0n,
677
678
  });
678
- expect(allowListIncentive._config).toEqual(defaultOptions.config);
679
- expect(allowListIncentive._account).toEqual(defaultOptions.account);
679
+ expect(allowListIncentive.config).toEqual(defaultOptions.config);
680
+ expect(allowListIncentive.account).toEqual(defaultOptions.account);
680
681
 
681
682
  const cgdaIncentive = core.CGDAIncentive({
682
683
  asset: zeroAddress,
@@ -686,8 +687,8 @@ describe("BoostCore", () => {
686
687
  totalBudget: 0n,
687
688
  manager: zeroAddress,
688
689
  });
689
- expect(cgdaIncentive._config).toEqual(defaultOptions.config);
690
- expect(cgdaIncentive._account).toEqual(defaultOptions.account);
690
+ expect(cgdaIncentive.config).toEqual(defaultOptions.config);
691
+ expect(cgdaIncentive.account).toEqual(defaultOptions.account);
691
692
 
692
693
  const erc20Incentive = core.ERC20Incentive({
693
694
  asset: zeroAddress,
@@ -695,16 +696,17 @@ describe("BoostCore", () => {
695
696
  reward: 0n,
696
697
  limit: 0n,
697
698
  });
698
- expect(erc20Incentive._config).toEqual(defaultOptions.config);
699
- expect(erc20Incentive._account).toEqual(defaultOptions.account);
699
+ expect(erc20Incentive.config).toEqual(defaultOptions.config);
700
+ expect(erc20Incentive.account).toEqual(defaultOptions.account);
700
701
 
701
702
  const erc20VariableIncentive = core.ERC20VariableIncentive({
702
703
  asset: zeroAddress,
703
704
  reward: 0n,
704
705
  limit: 0n,
706
+ manager: zeroAddress,
705
707
  });
706
- expect(erc20VariableIncentive._config).toEqual(defaultOptions.config);
707
- expect(erc20VariableIncentive._account).toEqual(defaultOptions.account);
708
+ expect(erc20VariableIncentive.config).toEqual(defaultOptions.config);
709
+ expect(erc20VariableIncentive.account).toEqual(defaultOptions.account);
708
710
 
709
711
  // const erc1155Incentive = core.ERC1155Incentive({
710
712
  // asset: zeroAddress,
@@ -722,12 +724,12 @@ describe("BoostCore", () => {
722
724
  reward: 0n,
723
725
  limit: 0n,
724
726
  });
725
- expect(pointsIncentive._config).toEqual(defaultOptions.config);
726
- expect(pointsIncentive._account).toEqual(defaultOptions.account);
727
+ expect(pointsIncentive.config).toEqual(defaultOptions.config);
728
+ expect(pointsIncentive.account).toEqual(defaultOptions.account);
727
729
 
728
730
  const signerValidator = core.SignerValidator(zeroAddress);
729
- expect(signerValidator._config).toEqual(defaultOptions.config);
730
- expect(signerValidator._account).toEqual(defaultOptions.account);
731
+ expect(signerValidator.config).toEqual(defaultOptions.config);
732
+ expect(signerValidator.account).toEqual(defaultOptions.account);
731
733
  });
732
734
 
733
735
  test("can subscribe to contract events", async () => {
@@ -776,6 +778,7 @@ describe("BoostCore", () => {
776
778
  const { core } = fixtures;
777
779
 
778
780
  const auth = core.PassthroughAuth();
781
+ // @ts-ignore
779
782
  await auth.deploy();
780
783
  await core.setCreateBoostAuth(auth);
781
784
  expect((await core.createBoostAuth()).toLowerCase()).toBe(
@@ -1032,6 +1035,8 @@ describe("Top-Up Incentives", () => {
1032
1035
  let boostId: bigint;
1033
1036
 
1034
1037
  beforeAll(async () => {
1038
+ fixtures = await loadFixture(deployFixtures(defaultOptions));
1039
+ budgets = await loadFixture(fundBudget(defaultOptions, fixtures));
1035
1040
  const { core } = fixtures;
1036
1041
  const { budget, erc20 } = budgets;
1037
1042
 
@@ -1078,12 +1083,9 @@ describe("Top-Up Incentives", () => {
1078
1083
  const { core } = fixtures;
1079
1084
  const { budget, erc20 } = budgets;
1080
1085
 
1081
- console.log("budget", budget.assertValidAddress());
1082
-
1083
1086
  const netTopup = parseEther("5");
1084
1087
 
1085
1088
  await core.topupIncentiveFromBudgetPreFee(boostId, 0n, netTopup, budget.assertValidAddress());
1086
- console.log("topup done");
1087
1089
 
1088
1090
  expect(await incentive.limit()).toBe(5n + 5n); // original limit 5 + topup 5
1089
1091
  });
@@ -1155,6 +1157,8 @@ describe("ERC20PeggedVariableCriteriaIncentive Top-Ups", () => {
1155
1157
  let erc721: MockERC721;
1156
1158
 
1157
1159
  beforeAll(async () => {
1160
+ fixtures = await loadFixture(deployFixtures(defaultOptions));
1161
+ budgets = await loadFixture(fundBudget(defaultOptions, fixtures));
1158
1162
  const { core } = fixtures;
1159
1163
  const { budget, erc20 } = budgets;
1160
1164
 
@@ -1285,6 +1289,13 @@ describe("ERC20PeggedVariableCriteriaIncentive Top-Ups", () => {
1285
1289
  });
1286
1290
 
1287
1291
  describe("ERC20PeggedVariableCriteriaIncentive with LimitedSignerValidator", () => {
1292
+ beforeAll(async () => {
1293
+ fixtures = await loadFixture(deployFixtures(defaultOptions));
1294
+ });
1295
+ beforeEach(async () => {
1296
+ budgets = await loadFixture(fundBudget(defaultOptions, fixtures));
1297
+ });
1298
+
1288
1299
  test("enforces validator claim limit", async () => {
1289
1300
  const referrer = accounts[1].account!;
1290
1301
  const signer = accounts[0];