@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.
- package/dist/Actions/Action.cjs +1 -1
- package/dist/Actions/Action.js +1 -1
- package/dist/Actions/EventAction.cjs +1 -1
- package/dist/Actions/EventAction.cjs.map +1 -1
- package/dist/Actions/EventAction.d.ts +25 -4
- package/dist/Actions/EventAction.d.ts.map +1 -1
- package/dist/Actions/EventAction.js +208 -184
- package/dist/Actions/EventAction.js.map +1 -1
- package/dist/{AllowList-DiU7g4Hs.js → AllowList-CWqAYlwr.js} +28 -28
- package/dist/{AllowList-DiU7g4Hs.js.map → AllowList-CWqAYlwr.js.map} +1 -1
- package/dist/{AllowList-BJ9HQGFs.cjs → AllowList-Lpqz7tn9.cjs} +2 -2
- package/dist/{AllowList-BJ9HQGFs.cjs.map → AllowList-Lpqz7tn9.cjs.map} +1 -1
- package/dist/AllowLists/AllowList.cjs +1 -1
- package/dist/AllowLists/AllowList.js +3 -3
- package/dist/AllowLists/SimpleAllowList.cjs +1 -1
- package/dist/AllowLists/SimpleAllowList.js +8 -8
- package/dist/AllowLists/SimpleDenyList.cjs +1 -1
- package/dist/AllowLists/SimpleDenyList.js +3 -3
- package/dist/Auth/PassthroughAuth.cjs +1 -1
- package/dist/Auth/PassthroughAuth.js +1 -1
- package/dist/BoostCore.cjs +2 -2
- package/dist/BoostCore.cjs.map +1 -1
- package/dist/BoostCore.d.ts +106 -23
- package/dist/BoostCore.d.ts.map +1 -1
- package/dist/BoostCore.js +518 -451
- package/dist/BoostCore.js.map +1 -1
- package/dist/BoostRegistry.cjs +1 -1
- package/dist/BoostRegistry.js +46 -46
- package/dist/{Budget-YIhV65cc.js → Budget-BPPXnBAK.js} +36 -36
- package/dist/{Budget-YIhV65cc.js.map → Budget-BPPXnBAK.js.map} +1 -1
- package/dist/{Budget-D_zhh1rh.cjs → Budget-rZm-AY09.cjs} +2 -2
- package/dist/{Budget-D_zhh1rh.cjs.map → Budget-rZm-AY09.cjs.map} +1 -1
- package/dist/Budgets/Budget.cjs +1 -1
- package/dist/Budgets/Budget.js +2 -2
- package/dist/Budgets/ManagedBudget.cjs +1 -1
- package/dist/Budgets/ManagedBudget.js +24 -24
- package/dist/Deployable/Contract.cjs +1 -1
- package/dist/Deployable/Contract.cjs.map +1 -1
- package/dist/Deployable/Contract.d.ts +8 -0
- package/dist/Deployable/Contract.d.ts.map +1 -1
- package/dist/Deployable/Contract.js +14 -4
- package/dist/Deployable/Contract.js.map +1 -1
- package/dist/Deployable/Deployable.cjs +1 -1
- package/dist/Deployable/Deployable.cjs.map +1 -1
- package/dist/Deployable/Deployable.d.ts +7 -0
- package/dist/Deployable/Deployable.d.ts.map +1 -1
- package/dist/Deployable/Deployable.js +13 -4
- package/dist/Deployable/Deployable.js.map +1 -1
- package/dist/Deployable/DeployableTarget.cjs +1 -1
- package/dist/Deployable/DeployableTarget.js +7 -7
- package/dist/Deployable/DeployableTargetWithRBAC.cjs +1 -1
- package/dist/Deployable/DeployableTargetWithRBAC.js +16 -16
- package/dist/{Incentive-CrnbYN_a.cjs → Incentive-Bse5BKbF.cjs} +2 -2
- package/dist/{Incentive-CrnbYN_a.cjs.map → Incentive-Bse5BKbF.cjs.map} +1 -1
- package/dist/{Incentive-CeoEla-t.js → Incentive-D1sYPD0W.js} +23 -23
- package/dist/{Incentive-CeoEla-t.js.map → Incentive-D1sYPD0W.js.map} +1 -1
- package/dist/Incentives/AllowListIncentive.cjs +1 -1
- package/dist/Incentives/AllowListIncentive.js +17 -17
- package/dist/Incentives/CGDAIncentive.cjs +1 -1
- package/dist/Incentives/CGDAIncentive.js +38 -38
- package/dist/Incentives/ERC20Incentive.cjs +1 -1
- package/dist/Incentives/ERC20Incentive.js +13 -13
- package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.cjs +1 -1
- package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.cjs.map +1 -1
- package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.d.ts +6 -6
- package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.js +22 -22
- package/dist/Incentives/ERC20PeggedVariableCriteriaIncentive.js.map +1 -1
- package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.cjs +1 -1
- package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.cjs.map +1 -1
- package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.d.ts +6 -6
- package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.js +91 -91
- package/dist/Incentives/ERC20PeggedVariableCriteriaIncentiveV2.js.map +1 -1
- package/dist/Incentives/ERC20VariableCriteriaIncentive.cjs +1 -1
- package/dist/Incentives/ERC20VariableCriteriaIncentive.cjs.map +1 -1
- package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts +6 -6
- package/dist/Incentives/ERC20VariableCriteriaIncentive.js +9 -9
- package/dist/Incentives/ERC20VariableCriteriaIncentive.js.map +1 -1
- package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.cjs +1 -1
- package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.cjs.map +1 -1
- package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.d.ts +6 -6
- package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.js +9 -9
- package/dist/Incentives/ERC20VariableCriteriaIncentiveV2.js.map +1 -1
- package/dist/Incentives/ERC20VariableIncentive.cjs +1 -1
- package/dist/Incentives/ERC20VariableIncentive.js +12 -12
- package/dist/Incentives/Incentive.cjs +1 -1
- package/dist/Incentives/Incentive.js +2 -2
- package/dist/Incentives/PointsIncentive.cjs +1 -1
- package/dist/Incentives/PointsIncentive.js +10 -10
- package/dist/{SimpleDenyList-Dr03aOeP.js → SimpleDenyList-BtEUdiAj.js} +14 -14
- package/dist/{SimpleDenyList-Dr03aOeP.js.map → SimpleDenyList-BtEUdiAj.js.map} +1 -1
- package/dist/{SimpleDenyList-7-VTqfsH.cjs → SimpleDenyList-DEoMIYhE.cjs} +2 -2
- package/dist/{SimpleDenyList-7-VTqfsH.cjs.map → SimpleDenyList-DEoMIYhE.cjs.map} +1 -1
- package/dist/{Validator-rYW7PMwW.cjs → Validator-DHS4vjSa.cjs} +2 -2
- package/dist/{Validator-rYW7PMwW.cjs.map → Validator-DHS4vjSa.cjs.map} +1 -1
- package/dist/{Validator-DgvB9wge.js → Validator-Kpvmj9Bs.js} +9 -9
- package/dist/{Validator-DgvB9wge.js.map → Validator-Kpvmj9Bs.js.map} +1 -1
- package/dist/Validators/LimitedSignerValidator.cjs +1 -1
- package/dist/Validators/LimitedSignerValidator.js +17 -17
- package/dist/Validators/SignerValidator.cjs +1 -1
- package/dist/Validators/SignerValidator.js +3 -3
- package/dist/Validators/Validator.cjs +1 -1
- package/dist/Validators/Validator.js +2 -2
- package/dist/{deployments-CHQ30INq.js → deployments-Coa8CGi2.js} +67 -67
- package/dist/{deployments-CHQ30INq.js.map → deployments-Coa8CGi2.js.map} +1 -1
- package/dist/{deployments-BjBgk03b.cjs → deployments-Dgzcz4Ev.cjs} +2 -2
- package/dist/deployments-Dgzcz4Ev.cjs.map +1 -0
- package/dist/deployments.json +46 -46
- package/dist/generated-BzLYuFx3.cjs +3 -0
- package/dist/generated-BzLYuFx3.cjs.map +1 -0
- package/dist/{generated-B6mEIx8i.js → generated-D6oDILUw.js} +250 -193
- package/dist/generated-D6oDILUw.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +185 -182
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/Actions/EventAction.test.ts +161 -1
- package/src/Actions/EventAction.ts +52 -5
- package/src/BoostCore.test.ts +34 -23
- package/src/BoostCore.ts +124 -26
- package/src/Deployable/Contract.ts +11 -0
- package/src/Deployable/Deployable.ts +10 -0
- package/src/utils.ts +0 -1
- package/dist/deployments-BjBgk03b.cjs.map +0 -1
- package/dist/generated-B6mEIx8i.js.map +0 -1
- package/dist/generated-dd4FN0Fo.cjs +0 -3
- 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
|
package/package.json
CHANGED
|
@@ -44,7 +44,9 @@ import {
|
|
|
44
44
|
packCriteriaFieldIndexes,
|
|
45
45
|
unpackCriteriaFieldIndexes,
|
|
46
46
|
isCriteriaFieldIndexTuple,
|
|
47
|
-
|
|
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
|
-
|
|
676
|
-
|
|
677
|
-
|
|
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.
|
package/src/BoostCore.test.ts
CHANGED
|
@@ -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.
|
|
652
|
-
expect(eventAction.
|
|
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.
|
|
656
|
-
expect(allowList.
|
|
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.
|
|
660
|
-
expect(denyList.
|
|
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.
|
|
664
|
-
expect(managedBudget.
|
|
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.
|
|
679
|
-
expect(allowListIncentive.
|
|
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.
|
|
690
|
-
expect(cgdaIncentive.
|
|
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.
|
|
699
|
-
expect(erc20Incentive.
|
|
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.
|
|
707
|
-
expect(erc20VariableIncentive.
|
|
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.
|
|
726
|
-
expect(pointsIncentive.
|
|
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.
|
|
730
|
-
expect(signerValidator.
|
|
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];
|