@boostxyz/sdk 2.1.1 → 2.2.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 (131) hide show
  1. package/dist/Actions/Action.cjs +1 -1
  2. package/dist/Actions/Action.cjs.map +1 -1
  3. package/dist/Actions/Action.d.ts +2 -1
  4. package/dist/Actions/Action.d.ts.map +1 -1
  5. package/dist/Actions/Action.js +14 -13
  6. package/dist/Actions/Action.js.map +1 -1
  7. package/dist/Actions/EventAction.cjs +1 -1
  8. package/dist/Actions/EventAction.cjs.map +1 -1
  9. package/dist/Actions/EventAction.d.ts.map +1 -1
  10. package/dist/Actions/EventAction.js +33 -33
  11. package/dist/Actions/EventAction.js.map +1 -1
  12. package/dist/AllowLists/AllowList.cjs +1 -1
  13. package/dist/AllowLists/AllowList.cjs.map +1 -1
  14. package/dist/AllowLists/AllowList.d.ts +2 -1
  15. package/dist/AllowLists/AllowList.d.ts.map +1 -1
  16. package/dist/AllowLists/AllowList.js +19 -18
  17. package/dist/AllowLists/AllowList.js.map +1 -1
  18. package/dist/AllowLists/SimpleAllowList.cjs +1 -1
  19. package/dist/AllowLists/SimpleAllowList.js +7 -7
  20. package/dist/AllowLists/SimpleDenyList.cjs +1 -1
  21. package/dist/AllowLists/SimpleDenyList.js +3 -3
  22. package/dist/Auth/PassthroughAuth.cjs +1 -1
  23. package/dist/Auth/PassthroughAuth.js +1 -1
  24. package/dist/BoostCore.cjs +2 -2
  25. package/dist/BoostCore.cjs.map +1 -1
  26. package/dist/BoostCore.d.ts +13 -4
  27. package/dist/BoostCore.d.ts.map +1 -1
  28. package/dist/BoostCore.js +58 -57
  29. package/dist/BoostCore.js.map +1 -1
  30. package/dist/BoostRegistry.cjs +1 -1
  31. package/dist/BoostRegistry.js +11 -11
  32. package/dist/{Budget-DpQgIZEx.js → Budget-B0q1S08L.js} +33 -32
  33. package/dist/{Budget-DpQgIZEx.js.map → Budget-B0q1S08L.js.map} +1 -1
  34. package/dist/{Budget-BxQMnsdx.cjs → Budget-BA_1sa1e.cjs} +2 -2
  35. package/dist/{Budget-BxQMnsdx.cjs.map → Budget-BA_1sa1e.cjs.map} +1 -1
  36. package/dist/Budgets/Budget.cjs +1 -1
  37. package/dist/Budgets/Budget.d.ts +2 -1
  38. package/dist/Budgets/Budget.d.ts.map +1 -1
  39. package/dist/Budgets/Budget.js +2 -2
  40. package/dist/Budgets/ManagedBudget.cjs +1 -1
  41. package/dist/Budgets/ManagedBudget.js +11 -11
  42. package/dist/Deployable/DeployableTarget.cjs +1 -1
  43. package/dist/Deployable/DeployableTarget.js +1 -1
  44. package/dist/Deployable/DeployableTargetWithRBAC.cjs +1 -1
  45. package/dist/Deployable/DeployableTargetWithRBAC.cjs.map +1 -1
  46. package/dist/Deployable/DeployableTargetWithRBAC.d.ts +158 -0
  47. package/dist/Deployable/DeployableTargetWithRBAC.d.ts.map +1 -1
  48. package/dist/Deployable/DeployableTargetWithRBAC.js +268 -31
  49. package/dist/Deployable/DeployableTargetWithRBAC.js.map +1 -1
  50. package/dist/Incentives/AllowListIncentive.cjs +1 -1
  51. package/dist/Incentives/AllowListIncentive.cjs.map +1 -1
  52. package/dist/Incentives/AllowListIncentive.js +27 -27
  53. package/dist/Incentives/AllowListIncentive.js.map +1 -1
  54. package/dist/Incentives/CGDAIncentive.cjs +1 -1
  55. package/dist/Incentives/CGDAIncentive.cjs.map +1 -1
  56. package/dist/Incentives/CGDAIncentive.js +9 -9
  57. package/dist/Incentives/CGDAIncentive.js.map +1 -1
  58. package/dist/Incentives/ERC20Incentive.cjs +1 -1
  59. package/dist/Incentives/ERC20Incentive.cjs.map +1 -1
  60. package/dist/Incentives/ERC20Incentive.js +30 -30
  61. package/dist/Incentives/ERC20Incentive.js.map +1 -1
  62. package/dist/Incentives/ERC20VariableCriteriaIncentive.cjs +1 -1
  63. package/dist/Incentives/ERC20VariableCriteriaIncentive.js +11 -11
  64. package/dist/Incentives/ERC20VariableIncentive.cjs +1 -1
  65. package/dist/Incentives/ERC20VariableIncentive.cjs.map +1 -1
  66. package/dist/Incentives/ERC20VariableIncentive.js +12 -12
  67. package/dist/Incentives/ERC20VariableIncentive.js.map +1 -1
  68. package/dist/Incentives/Incentive.cjs +1 -1
  69. package/dist/Incentives/Incentive.cjs.map +1 -1
  70. package/dist/Incentives/Incentive.d.ts +2 -1
  71. package/dist/Incentives/Incentive.d.ts.map +1 -1
  72. package/dist/Incentives/Incentive.js +29 -28
  73. package/dist/Incentives/Incentive.js.map +1 -1
  74. package/dist/Incentives/PointsIncentive.cjs +1 -1
  75. package/dist/Incentives/PointsIncentive.cjs.map +1 -1
  76. package/dist/Incentives/PointsIncentive.js +25 -25
  77. package/dist/Incentives/PointsIncentive.js.map +1 -1
  78. package/dist/{SimpleDenyList-CA24drhL.cjs → SimpleDenyList-DrQrJ14i.cjs} +2 -2
  79. package/dist/{SimpleDenyList-CA24drhL.cjs.map → SimpleDenyList-DrQrJ14i.cjs.map} +1 -1
  80. package/dist/{SimpleDenyList-UHgnaOb_.js → SimpleDenyList-DuCoaOlG.js} +9 -9
  81. package/dist/{SimpleDenyList-UHgnaOb_.js.map → SimpleDenyList-DuCoaOlG.js.map} +1 -1
  82. package/dist/Validators/LimitedSignerValidator.cjs +1 -1
  83. package/dist/Validators/LimitedSignerValidator.js +7 -7
  84. package/dist/Validators/SignerValidator.cjs +1 -1
  85. package/dist/Validators/SignerValidator.js +5 -5
  86. package/dist/Validators/Validator.cjs +1 -1
  87. package/dist/Validators/Validator.cjs.map +1 -1
  88. package/dist/Validators/Validator.d.ts +2 -1
  89. package/dist/Validators/Validator.d.ts.map +1 -1
  90. package/dist/Validators/Validator.js +22 -21
  91. package/dist/Validators/Validator.js.map +1 -1
  92. package/dist/deployments-BucJ-gwk.cjs +2 -0
  93. package/dist/deployments-BucJ-gwk.cjs.map +1 -0
  94. package/dist/deployments-CQu0bLhU.js +102 -0
  95. package/dist/deployments-CQu0bLhU.js.map +1 -0
  96. package/dist/deployments.json +77 -74
  97. package/dist/{generated-B0XfMfoq.js → generated-1ZT_mHJx.js} +673 -450
  98. package/dist/generated-1ZT_mHJx.js.map +1 -0
  99. package/dist/generated-CgBgbMNe.cjs +3 -0
  100. package/dist/generated-CgBgbMNe.cjs.map +1 -0
  101. package/dist/index.cjs +1 -1
  102. package/dist/index.js +3 -3
  103. package/package.json +2 -2
  104. package/src/Actions/Action.ts +3 -0
  105. package/src/Actions/EventAction.test.ts +49 -2
  106. package/src/Actions/EventAction.ts +12 -4
  107. package/src/AllowLists/AllowList.ts +3 -0
  108. package/src/BoostCore.ts +16 -11
  109. package/src/Budgets/Budget.ts +3 -0
  110. package/src/Deployable/DeployableTargetWithRBAC.test.ts +175 -0
  111. package/src/Deployable/DeployableTargetWithRBAC.ts +281 -0
  112. package/src/Incentives/AllowListIncentive.test.ts +48 -0
  113. package/src/Incentives/AllowListIncentive.ts +1 -1
  114. package/src/Incentives/CGDAIncentive.test.ts +50 -0
  115. package/src/Incentives/CGDAIncentive.ts +1 -1
  116. package/src/Incentives/ERC1155Incentive.ts +1 -1
  117. package/src/Incentives/ERC20Incentive.test.ts +49 -0
  118. package/src/Incentives/ERC20Incentive.ts +1 -1
  119. package/src/Incentives/ERC20VariableIncentive.test.ts +48 -0
  120. package/src/Incentives/ERC20VariableIncentive.ts +1 -1
  121. package/src/Incentives/Incentive.ts +3 -0
  122. package/src/Incentives/PointsIncentive.test.ts +51 -0
  123. package/src/Incentives/PointsIncentive.ts +1 -1
  124. package/src/Validators/Validator.ts +3 -0
  125. package/dist/deployments-BDumesUK.cjs +0 -2
  126. package/dist/deployments-BDumesUK.cjs.map +0 -1
  127. package/dist/deployments-DvYsMioW.js +0 -99
  128. package/dist/deployments-DvYsMioW.js.map +0 -1
  129. package/dist/generated-B0XfMfoq.js.map +0 -1
  130. package/dist/generated-pNKCp_Ez.cjs +0 -3
  131. package/dist/generated-pNKCp_Ez.cjs.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("./BoostRegistry.cjs"),n=require("./BoostCore.cjs"),A=require("./Boost.cjs"),u=require("./Actions/Action.cjs"),a=require("./Actions/EventAction.cjs"),E=require("./AllowLists/AllowList.cjs"),y=require("./AllowLists/SimpleAllowList.cjs"),C=require("./SimpleDenyList-CA24drhL.cjs"),l=require("./Budget-BxQMnsdx.cjs"),o=require("./Budgets/ManagedBudget.cjs"),D=require("./Deployable/Deployable.cjs"),T=require("./Deployable/Contract.cjs"),V=require("./Deployable/DeployableTarget.cjs"),I=require("./Deployable/DeployableTargetWithRBAC.cjs"),m=require("./Incentives/AllowListIncentive.cjs"),S=require("./Incentives/CGDAIncentive.cjs"),v=require("./Incentives/ERC20Incentive.cjs"),P=require("./Incentives/ERC20VariableIncentive.cjs"),g=require("./Incentives/ERC20VariableCriteriaIncentive.cjs"),b=require("./Incentives/Incentive.cjs"),R=require("./Incentives/PointsIncentive.cjs"),d=require("./Validators/SignerValidator.cjs"),s=require("./Validators/LimitedSignerValidator.cjs"),p=require("./Validators/Validator.cjs"),e=require("./errors.cjs"),i=require("./utils.cjs"),B=require("./claiming.cjs"),t=require("./transfers.cjs"),L=require("./Auth/PassthroughAuth.cjs"),r=require("./generated-pNKCp_Ez.cjs");exports.BOOST_REGISTRY_ADDRESS=c.BOOST_REGISTRY_ADDRESS;exports.BOOST_REGISTRY_ADDRESSES=c.BOOST_REGISTRY_ADDRESSES;exports.BoostRegistry=c.BoostRegistry;exports.BOOST_CORE_ADDRESS=n.BOOST_CORE_ADDRESS;exports.BOOST_CORE_ADDRESSES=n.BOOST_CORE_ADDRESSES;exports.BoostCore=n.BoostCore;exports.FEE_DENOMINATOR=n.FEE_DENOMINATOR;exports.Boost=A.Boost;exports.prepareBoostPayload=A.prepareBoostPayload;exports.ActionByComponentInterface=u.ActionByComponentInterface;exports.actionFromAddress=u.actionFromAddress;exports.EventAction=a.EventAction;exports.FilterType=a.FilterType;exports.PrimitiveType=a.PrimitiveType;exports.SignatureType=a.SignatureType;exports.anyActionParameter=a.anyActionParameter;exports.isEventActionPayloadSimple=a.isEventActionPayloadSimple;exports.prepareEventActionPayload=a.prepareEventActionPayload;exports.transactionSenderClaimant=a.transactionSenderClaimant;exports.AllowListByComponentInterface=E.AllowListByComponentInterface;exports.OpenAllowList=E.OpenAllowList;exports.allowListFromAddress=E.allowListFromAddress;exports.LIST_MANAGER_ROLE=y.LIST_MANAGER_ROLE;exports.SimpleAllowList=y.SimpleAllowList;exports.prepareSimpleAllowListPayload=y.prepareSimpleAllowListPayload;exports.SimpleDenyList=C.SimpleDenyList;exports.prepareSimpleDenyListPayload=C.prepareSimpleDenyListPayload;exports.BudgetByComponentInterface=l.BudgetByComponentInterface;exports.ManagedBudgetWithFees=l.ManagedBudgetWithFees;exports.budgetFromAddress=l.budgetFromAddress;exports.prepareManagedBudgetWithFeesPayload=l.prepareManagedBudgetWithFeesPayload;exports.ManagedBudget=o.ManagedBudget;exports.ManagedBudgetRoles=o.ManagedBudgetRoles;exports.isERC1155TransferPayload=o.isERC1155TransferPayload;exports.isFungibleTransfer=o.isFungibleTransfer;exports.prepareManagedBudgetPayload=o.prepareManagedBudgetPayload;exports.prepareTransfer=o.prepareTransfer;exports.Deployable=D.Deployable;exports.Contract=T.Contract;exports.DeployableTarget=V.DeployableTarget;exports.DeployableTargetWithRBAC=I.DeployableTargetWithRBAC;exports.Roles=I.Roles;exports.AllowListIncentive=m.AllowListIncentive;exports.prepareAllowListIncentivePayload=m.prepareAllowListIncentivePayload;exports.CGDAIncentive=S.CGDAIncentive;exports.prepareCGDAIncentivePayload=S.prepareCGDAIncentivePayload;exports.ERC20Incentive=v.ERC20Incentive;exports.prepareERC20IncentivePayload=v.prepareERC20IncentivePayload;exports.ERC20VariableIncentive=P.ERC20VariableIncentive;exports.prepareERC20VariableIncentivePayload=P.prepareERC20VariableIncentivePayload;exports.ERC20VariableCriteriaIncentive=g.ERC20VariableCriteriaIncentive;exports.gasRebateIncentiveCriteria=g.gasRebateIncentiveCriteria;exports.prepareERC20VariableCriteriaIncentivePayload=g.prepareERC20VariableCriteriaIncentivePayload;exports.IncentiveByComponentInterface=b.IncentiveByComponentInterface;exports.incentiveFromAddress=b.incentiveFromAddress;exports.PointsIncentive=R.PointsIncentive;exports.preparePointsIncentivePayload=R.preparePointsIncentivePayload;exports.SignerValidator=d.SignerValidator;exports.prepareSignerValidatorClaimDataPayload=d.prepareSignerValidatorClaimDataPayload;exports.prepareSignerValidatorInputParams=d.prepareSignerValidatorInputParams;exports.prepareSignerValidatorPayload=d.prepareSignerValidatorPayload;exports.LimitedSignerValidator=s.LimitedSignerValidator;exports.prepareLimitedSignerValidatorClaimDataPayload=s.prepareLimitedSignerValidatorClaimDataPayload;exports.prepareLimitedSignerValidatorInputParams=s.prepareLimitedSignerValidatorInputParams;exports.prepareLimitedSignerValidatorPayload=s.prepareLimitedSignerValidatorPayload;exports.BoostValidatorEOA=p.BoostValidatorEOA;exports.ValidatorByComponentInterface=p.ValidatorByComponentInterface;exports.decodeClaimData=p.decodeClaimData;exports.validatorFromAddress=p.validatorFromAddress;exports.BoostCoreNoIdentifierEmitted=e.BoostCoreNoIdentifierEmitted;exports.BoostNotFoundError=e.BoostNotFoundError;exports.BudgetMustAuthorizeBoostCore=e.BudgetMustAuthorizeBoostCore;exports.ContractAddressRequiredError=e.ContractAddressRequiredError;exports.DecodedArgsError=e.DecodedArgsError;exports.DecodedArgsMalformedError=e.DecodedArgsMalformedError;exports.DeployableAlreadyDeployedError=e.DeployableAlreadyDeployedError;exports.DeployableBuildParametersUnspecifiedError=e.DeployableBuildParametersUnspecifiedError;exports.DeployableMissingPayloadError=e.DeployableMissingPayloadError;exports.DeployableUnknownOwnerProvidedError=e.DeployableUnknownOwnerProvidedError;exports.DeployableWagmiConfigurationRequiredError=e.DeployableWagmiConfigurationRequiredError;exports.FieldActionValidationError=e.FieldActionValidationError;exports.FieldValueNotComparableError=e.FieldValueNotComparableError;exports.FieldValueUndefinedError=e.FieldValueUndefinedError;exports.FunctionDataDecodeError=e.FunctionDataDecodeError;exports.IncentiveCriteriaNotFoundError=e.IncentiveCriteriaNotFoundError;exports.IncentiveNotCloneableError=e.IncentiveNotCloneableError;exports.InvalidComponentInterfaceError=e.InvalidComponentInterfaceError;exports.InvalidCriteriaTypeError=e.InvalidCriteriaTypeError;exports.InvalidNumericalCriteriaError=e.InvalidNumericalCriteriaError;exports.InvalidProtocolChainIdError=e.InvalidProtocolChainIdError;exports.MustInitializeBudgetError=e.MustInitializeBudgetError;exports.NoConnectedChainIdError=e.NoConnectedChainIdError;exports.NoContractAddressUponReceiptError=e.NoContractAddressUponReceiptError;exports.NoEventActionStepsProvidedError=e.NoEventActionStepsProvidedError;exports.NoMatchingLogsError=e.NoMatchingLogsError;exports.TooManyEventActionStepsProvidedError=e.TooManyEventActionStepsProvidedError;exports.UnknownTransferPayloadSupplied=e.UnknownTransferPayloadSupplied;exports.UnparseableAbiParamError=e.UnparseableAbiParamError;exports.UnrecognizedFilterTypeError=e.UnrecognizedFilterTypeError;exports.ValidationAbiMissingError=e.ValidationAbiMissingError;exports.CheatCodes=i.CheatCodes;exports.RegistryType=i.RegistryType;exports.assertValidAddressByChainId=i.assertValidAddressByChainId;exports.awaitResult=i.awaitResult;exports.bytes4=i.bytes4;exports.getDeployedContractAddress=i.getDeployedContractAddress;exports.getErc20Balance=i.getErc20Balance;exports.StrategyType=B.StrategyType;exports.prepareClaimPayload=B.prepareClaimPayload;exports.AssetType=t.AssetType;exports.prepareERC1155Payload=t.prepareERC1155Payload;exports.prepareERC1155Transfer=t.prepareERC1155Transfer;exports.prepareFungiblePayload=t.prepareFungiblePayload;exports.prepareFungibleTransfer=t.prepareFungibleTransfer;exports.prepareTransferPayload=t.prepareTransferPayload;exports.PassthroughAuth=L.PassthroughAuth;exports.allowListIncentiveAbi=r.z;exports.boostCoreAbi=r.I;exports.boostRegistryAbi=r.ue;exports.cgdaIncentiveAbi=r.w;exports.erc20IncentiveAbi=r.m;exports.erc20VariableCriteriaIncentiveAbi=r.b;exports.erc20VariableIncentiveAbi=r.T;exports.limitedSignerValidatorAbi=r.H;exports.managedBudgetAbi=r.f;exports.managedBudgetWithFeesAbi=r.o;exports.passthroughAuthAbi=r.Le;exports.pointsIncentiveAbi=r.h;exports.rbacAbi=r.E;exports.signerValidatorAbi=r.F;exports.simpleAllowListAbi=r.R;exports.simpleDenyListAbi=r.O;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("./BoostRegistry.cjs"),n=require("./BoostCore.cjs"),A=require("./Boost.cjs"),u=require("./Actions/Action.cjs"),a=require("./Actions/EventAction.cjs"),E=require("./AllowLists/AllowList.cjs"),y=require("./AllowLists/SimpleAllowList.cjs"),C=require("./SimpleDenyList-DrQrJ14i.cjs"),l=require("./Budget-BA_1sa1e.cjs"),o=require("./Budgets/ManagedBudget.cjs"),D=require("./Deployable/Deployable.cjs"),T=require("./Deployable/Contract.cjs"),V=require("./Deployable/DeployableTarget.cjs"),I=require("./Deployable/DeployableTargetWithRBAC.cjs"),m=require("./Incentives/AllowListIncentive.cjs"),S=require("./Incentives/CGDAIncentive.cjs"),v=require("./Incentives/ERC20Incentive.cjs"),P=require("./Incentives/ERC20VariableIncentive.cjs"),g=require("./Incentives/ERC20VariableCriteriaIncentive.cjs"),b=require("./Incentives/Incentive.cjs"),R=require("./Incentives/PointsIncentive.cjs"),d=require("./Validators/SignerValidator.cjs"),s=require("./Validators/LimitedSignerValidator.cjs"),p=require("./Validators/Validator.cjs"),e=require("./errors.cjs"),i=require("./utils.cjs"),B=require("./claiming.cjs"),t=require("./transfers.cjs"),L=require("./Auth/PassthroughAuth.cjs"),r=require("./generated-CgBgbMNe.cjs");exports.BOOST_REGISTRY_ADDRESS=c.BOOST_REGISTRY_ADDRESS;exports.BOOST_REGISTRY_ADDRESSES=c.BOOST_REGISTRY_ADDRESSES;exports.BoostRegistry=c.BoostRegistry;exports.BOOST_CORE_ADDRESS=n.BOOST_CORE_ADDRESS;exports.BOOST_CORE_ADDRESSES=n.BOOST_CORE_ADDRESSES;exports.BoostCore=n.BoostCore;exports.FEE_DENOMINATOR=n.FEE_DENOMINATOR;exports.Boost=A.Boost;exports.prepareBoostPayload=A.prepareBoostPayload;exports.ActionByComponentInterface=u.ActionByComponentInterface;exports.actionFromAddress=u.actionFromAddress;exports.EventAction=a.EventAction;exports.FilterType=a.FilterType;exports.PrimitiveType=a.PrimitiveType;exports.SignatureType=a.SignatureType;exports.anyActionParameter=a.anyActionParameter;exports.isEventActionPayloadSimple=a.isEventActionPayloadSimple;exports.prepareEventActionPayload=a.prepareEventActionPayload;exports.transactionSenderClaimant=a.transactionSenderClaimant;exports.AllowListByComponentInterface=E.AllowListByComponentInterface;exports.OpenAllowList=E.OpenAllowList;exports.allowListFromAddress=E.allowListFromAddress;exports.LIST_MANAGER_ROLE=y.LIST_MANAGER_ROLE;exports.SimpleAllowList=y.SimpleAllowList;exports.prepareSimpleAllowListPayload=y.prepareSimpleAllowListPayload;exports.SimpleDenyList=C.SimpleDenyList;exports.prepareSimpleDenyListPayload=C.prepareSimpleDenyListPayload;exports.BudgetByComponentInterface=l.BudgetByComponentInterface;exports.ManagedBudgetWithFees=l.ManagedBudgetWithFees;exports.budgetFromAddress=l.budgetFromAddress;exports.prepareManagedBudgetWithFeesPayload=l.prepareManagedBudgetWithFeesPayload;exports.ManagedBudget=o.ManagedBudget;exports.ManagedBudgetRoles=o.ManagedBudgetRoles;exports.isERC1155TransferPayload=o.isERC1155TransferPayload;exports.isFungibleTransfer=o.isFungibleTransfer;exports.prepareManagedBudgetPayload=o.prepareManagedBudgetPayload;exports.prepareTransfer=o.prepareTransfer;exports.Deployable=D.Deployable;exports.Contract=T.Contract;exports.DeployableTarget=V.DeployableTarget;exports.DeployableTargetWithRBAC=I.DeployableTargetWithRBAC;exports.Roles=I.Roles;exports.AllowListIncentive=m.AllowListIncentive;exports.prepareAllowListIncentivePayload=m.prepareAllowListIncentivePayload;exports.CGDAIncentive=S.CGDAIncentive;exports.prepareCGDAIncentivePayload=S.prepareCGDAIncentivePayload;exports.ERC20Incentive=v.ERC20Incentive;exports.prepareERC20IncentivePayload=v.prepareERC20IncentivePayload;exports.ERC20VariableIncentive=P.ERC20VariableIncentive;exports.prepareERC20VariableIncentivePayload=P.prepareERC20VariableIncentivePayload;exports.ERC20VariableCriteriaIncentive=g.ERC20VariableCriteriaIncentive;exports.gasRebateIncentiveCriteria=g.gasRebateIncentiveCriteria;exports.prepareERC20VariableCriteriaIncentivePayload=g.prepareERC20VariableCriteriaIncentivePayload;exports.IncentiveByComponentInterface=b.IncentiveByComponentInterface;exports.incentiveFromAddress=b.incentiveFromAddress;exports.PointsIncentive=R.PointsIncentive;exports.preparePointsIncentivePayload=R.preparePointsIncentivePayload;exports.SignerValidator=d.SignerValidator;exports.prepareSignerValidatorClaimDataPayload=d.prepareSignerValidatorClaimDataPayload;exports.prepareSignerValidatorInputParams=d.prepareSignerValidatorInputParams;exports.prepareSignerValidatorPayload=d.prepareSignerValidatorPayload;exports.LimitedSignerValidator=s.LimitedSignerValidator;exports.prepareLimitedSignerValidatorClaimDataPayload=s.prepareLimitedSignerValidatorClaimDataPayload;exports.prepareLimitedSignerValidatorInputParams=s.prepareLimitedSignerValidatorInputParams;exports.prepareLimitedSignerValidatorPayload=s.prepareLimitedSignerValidatorPayload;exports.BoostValidatorEOA=p.BoostValidatorEOA;exports.ValidatorByComponentInterface=p.ValidatorByComponentInterface;exports.decodeClaimData=p.decodeClaimData;exports.validatorFromAddress=p.validatorFromAddress;exports.BoostCoreNoIdentifierEmitted=e.BoostCoreNoIdentifierEmitted;exports.BoostNotFoundError=e.BoostNotFoundError;exports.BudgetMustAuthorizeBoostCore=e.BudgetMustAuthorizeBoostCore;exports.ContractAddressRequiredError=e.ContractAddressRequiredError;exports.DecodedArgsError=e.DecodedArgsError;exports.DecodedArgsMalformedError=e.DecodedArgsMalformedError;exports.DeployableAlreadyDeployedError=e.DeployableAlreadyDeployedError;exports.DeployableBuildParametersUnspecifiedError=e.DeployableBuildParametersUnspecifiedError;exports.DeployableMissingPayloadError=e.DeployableMissingPayloadError;exports.DeployableUnknownOwnerProvidedError=e.DeployableUnknownOwnerProvidedError;exports.DeployableWagmiConfigurationRequiredError=e.DeployableWagmiConfigurationRequiredError;exports.FieldActionValidationError=e.FieldActionValidationError;exports.FieldValueNotComparableError=e.FieldValueNotComparableError;exports.FieldValueUndefinedError=e.FieldValueUndefinedError;exports.FunctionDataDecodeError=e.FunctionDataDecodeError;exports.IncentiveCriteriaNotFoundError=e.IncentiveCriteriaNotFoundError;exports.IncentiveNotCloneableError=e.IncentiveNotCloneableError;exports.InvalidComponentInterfaceError=e.InvalidComponentInterfaceError;exports.InvalidCriteriaTypeError=e.InvalidCriteriaTypeError;exports.InvalidNumericalCriteriaError=e.InvalidNumericalCriteriaError;exports.InvalidProtocolChainIdError=e.InvalidProtocolChainIdError;exports.MustInitializeBudgetError=e.MustInitializeBudgetError;exports.NoConnectedChainIdError=e.NoConnectedChainIdError;exports.NoContractAddressUponReceiptError=e.NoContractAddressUponReceiptError;exports.NoEventActionStepsProvidedError=e.NoEventActionStepsProvidedError;exports.NoMatchingLogsError=e.NoMatchingLogsError;exports.TooManyEventActionStepsProvidedError=e.TooManyEventActionStepsProvidedError;exports.UnknownTransferPayloadSupplied=e.UnknownTransferPayloadSupplied;exports.UnparseableAbiParamError=e.UnparseableAbiParamError;exports.UnrecognizedFilterTypeError=e.UnrecognizedFilterTypeError;exports.ValidationAbiMissingError=e.ValidationAbiMissingError;exports.CheatCodes=i.CheatCodes;exports.RegistryType=i.RegistryType;exports.assertValidAddressByChainId=i.assertValidAddressByChainId;exports.awaitResult=i.awaitResult;exports.bytes4=i.bytes4;exports.getDeployedContractAddress=i.getDeployedContractAddress;exports.getErc20Balance=i.getErc20Balance;exports.StrategyType=B.StrategyType;exports.prepareClaimPayload=B.prepareClaimPayload;exports.AssetType=t.AssetType;exports.prepareERC1155Payload=t.prepareERC1155Payload;exports.prepareERC1155Transfer=t.prepareERC1155Transfer;exports.prepareFungiblePayload=t.prepareFungiblePayload;exports.prepareFungibleTransfer=t.prepareFungibleTransfer;exports.prepareTransferPayload=t.prepareTransferPayload;exports.PassthroughAuth=L.PassthroughAuth;exports.allowListIncentiveAbi=r.z;exports.boostCoreAbi=r.I;exports.boostRegistryAbi=r.ue;exports.cgdaIncentiveAbi=r.w;exports.erc20IncentiveAbi=r.m;exports.erc20VariableCriteriaIncentiveAbi=r.b;exports.erc20VariableIncentiveAbi=r.T;exports.limitedSignerValidatorAbi=r.H;exports.managedBudgetAbi=r.f;exports.managedBudgetWithFeesAbi=r.o;exports.passthroughAuthAbi=r.Le;exports.pointsIncentiveAbi=r.h;exports.rbacAbi=r.E;exports.signerValidatorAbi=r.F;exports.simpleAllowListAbi=r.R;exports.simpleDenyListAbi=r.O;
2
2
  //# sourceMappingURL=index.cjs.map
package/dist/index.js CHANGED
@@ -5,8 +5,8 @@ import { ActionByComponentInterface as A, actionFromAddress as y } from "./Actio
5
5
  import { EventAction as f, FilterType as C, PrimitiveType as b, SignatureType as I, anyActionParameter as S, isEventActionPayloadSimple as u, prepareEventActionPayload as v, transactionSenderClaimant as P } from "./Actions/EventAction.js";
6
6
  import { AllowListByComponentInterface as B, OpenAllowList as D, allowListFromAddress as x } from "./AllowLists/AllowList.js";
7
7
  import { LIST_MANAGER_ROLE as V, SimpleAllowList as F, prepareSimpleAllowListPayload as L } from "./AllowLists/SimpleAllowList.js";
8
- import { S as O, p as M } from "./SimpleDenyList-UHgnaOb_.js";
9
- import { B as N, M as _, b as U, p as G } from "./Budget-DpQgIZEx.js";
8
+ import { S as O, p as M } from "./SimpleDenyList-DuCoaOlG.js";
9
+ import { B as N, M as _, b as U, p as G } from "./Budget-B0q1S08L.js";
10
10
  import { ManagedBudget as z, ManagedBudgetRoles as k, isERC1155TransferPayload as q, isFungibleTransfer as Y, prepareManagedBudgetPayload as H, prepareTransfer as j } from "./Budgets/ManagedBudget.js";
11
11
  import { Deployable as K } from "./Deployable/Deployable.js";
12
12
  import { Contract as X } from "./Deployable/Contract.js";
@@ -27,7 +27,7 @@ import { CheatCodes as br, RegistryType as Ir, assertValidAddressByChainId as Sr
27
27
  import { StrategyType as Dr, prepareClaimPayload as xr } from "./claiming.js";
28
28
  import { AssetType as Vr, prepareERC1155Payload as Fr, prepareERC1155Transfer as Lr, prepareFungiblePayload as hr, prepareFungibleTransfer as Or, prepareTransferPayload as Mr } from "./transfers.js";
29
29
  import { PassthroughAuth as Nr } from "./Auth/PassthroughAuth.js";
30
- import { z as Ur, I as Gr, u as Wr, w as zr, m as kr, b as qr, T as Yr, H as Hr, f as jr, o as Jr, L as Kr, h as Qr, E as Xr, F as Zr, R as $r, O as ea } from "./generated-B0XfMfoq.js";
30
+ import { z as Ur, I as Gr, u as Wr, w as zr, m as kr, b as qr, T as Yr, H as Hr, f as jr, o as Jr, L as Kr, h as Qr, E as Xr, F as Zr, R as $r, O as ea } from "./generated-1ZT_mHJx.js";
31
31
  export {
32
32
  A as ActionByComponentInterface,
33
33
  B as AllowListByComponentInterface,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boostxyz/sdk",
3
- "version": "2.1.1",
3
+ "version": "2.2.0",
4
4
  "license": "GPL-3.0-or-later",
5
5
  "type": "module",
6
6
  "files": [
@@ -213,7 +213,7 @@
213
213
  }
214
214
  },
215
215
  "dependencies": {
216
- "ts-pattern": "5.4.0"
216
+ "ts-pattern": "5.5.0"
217
217
  },
218
218
  "peerDependencies": {
219
219
  "@wagmi/core": "2.x",
@@ -4,6 +4,7 @@ import { readContract } from '@wagmi/core';
4
4
  import type { Address, Hex } from 'viem';
5
5
  import type { DeployableOptions } from '../Deployable/Deployable';
6
6
  import { InvalidComponentInterfaceError } from '../errors';
7
+ import type { ReadParams } from '../utils';
7
8
  import { EventAction } from './EventAction';
8
9
 
9
10
  export {
@@ -44,11 +45,13 @@ export const ActionByComponentInterface = {
44
45
  export async function actionFromAddress(
45
46
  options: DeployableOptions,
46
47
  address: Address,
48
+ params?: ReadParams,
47
49
  ) {
48
50
  const interfaceId = (await readContract(options.config, {
49
51
  abi: aActionAbi,
50
52
  functionName: 'getComponentInterface',
51
53
  address,
54
+ ...params,
52
55
  })) as keyof typeof ActionByComponentInterface;
53
56
  const Ctor = ActionByComponentInterface[interfaceId];
54
57
  if (!Ctor) {
@@ -982,7 +982,54 @@ describe("EventAction Func Selector", () => {
982
982
  ).toBe(true);
983
983
  });
984
984
 
985
- test("validates action step with `notBeforeBlockNumber` lower than tx blockNumber", async () => {
985
+ test("validates event action step with `notBeforeBlockNumber` lower than tx blockNumber", async () => {
986
+ const action = await loadFixture(cloneEventAction(fixtures, erc721));
987
+ const actionSteps = await action.getActionSteps();
988
+ const actionStep = actionSteps[0]!;
989
+ const recipient = accounts[1].account;
990
+ const { hash } = await erc721.mintRaw(recipient, {
991
+ value: parseEther(".1"),
992
+ });
993
+
994
+ const criteriaMatch = await action.isActionStepValid(actionStep, {
995
+ notBeforeBlockNumber: BigInt(Number.MAX_SAFE_INTEGER),
996
+ hash,
997
+ knownSignatures: allKnownSignatures,
998
+ });
999
+
1000
+ expect(criteriaMatch).toBe(false);
1001
+ });
1002
+
1003
+ test("validates event action step with `notBeforeBlockNumber` greater than/equal to tx blockNumber", async () => {
1004
+ const action = await loadFixture(cloneEventAction(fixtures, erc721));
1005
+ const actionSteps = await action.getActionSteps();
1006
+ const actionStep = actionSteps[0]!;
1007
+ const recipient = accounts[1].account;
1008
+ const { hash } = await erc721.mintRaw(recipient, {
1009
+ value: parseEther(".1"),
1010
+ });
1011
+ const receipt = await getTransactionReceipt(defaultOptions.config, {
1012
+ hash,
1013
+ });
1014
+
1015
+ const eqMatch = await action.isActionStepValid(actionStep, {
1016
+ notBeforeBlockNumber: receipt.blockNumber,
1017
+ hash,
1018
+ knownSignatures: allKnownSignatures,
1019
+ });
1020
+
1021
+ expect(eqMatch).toBe(true);
1022
+ const gtMatch = await action.isActionStepValid(actionStep, {
1023
+ notBeforeBlockNumber: receipt.blockNumber - 1n,
1024
+ hash,
1025
+ knownSignatures: allKnownSignatures,
1026
+ });
1027
+
1028
+ expect(gtMatch).toBe(true);
1029
+ });
1030
+
1031
+
1032
+ test("validates function action step with `notBeforeBlockNumber` lower than tx blockNumber", async () => {
986
1033
  const action = await loadFixture(cloneFunctionAction(fixtures, erc721));
987
1034
  const actionSteps = await action.getActionSteps();
988
1035
  const actionStep = actionSteps[0]!;
@@ -1000,7 +1047,7 @@ describe("EventAction Func Selector", () => {
1000
1047
  expect(criteriaMatch).toBe(false);
1001
1048
  });
1002
1049
 
1003
- test("validates action step with `notBeforeBlockNumber` greater than/equal to tx blockNumber", async () => {
1050
+ test("validates function action step with `notBeforeBlockNumber` greater than/equal to tx blockNumber", async () => {
1004
1051
  const action = await loadFixture(cloneFunctionAction(fixtures, erc721));
1005
1052
  const actionSteps = await action.getActionSteps();
1006
1053
  const actionStep = actionSteps[0]!;
@@ -708,8 +708,12 @@ export class EventAction extends DeployableTarget<
708
708
  ...params,
709
709
  chainId: actionStep.chainid,
710
710
  });
711
- if (params.notBeforeBlockNumber)
712
- return receipt.blockNumber >= params.notBeforeBlockNumber;
711
+ if (
712
+ params.notBeforeBlockNumber &&
713
+ receipt.blockNumber < params.notBeforeBlockNumber
714
+ ) {
715
+ return false;
716
+ }
713
717
  const decodedLogs = receipt.logs
714
718
  .filter((log) => log.topics[0] === toEventSelector(event))
715
719
  .map((log) => {
@@ -730,8 +734,12 @@ export class EventAction extends DeployableTarget<
730
734
  ...params,
731
735
  chainId: actionStep.chainid,
732
736
  });
733
- if (params.notBeforeBlockNumber)
734
- return transaction.blockNumber >= params.notBeforeBlockNumber;
737
+ if (
738
+ params.notBeforeBlockNumber &&
739
+ transaction.blockNumber < params.notBeforeBlockNumber
740
+ ) {
741
+ return false;
742
+ }
735
743
  return this.isActionFunctionValid(actionStep, transaction, params);
736
744
  }
737
745
  }
@@ -7,6 +7,7 @@ import { readContract } from '@wagmi/core';
7
7
  import type { Address, Hex } from 'viem';
8
8
  import type { DeployableOptions } from '../Deployable/Deployable';
9
9
  import { InvalidComponentInterfaceError } from '../errors';
10
+ import type { ReadParams } from '../utils';
10
11
  import { OpenAllowList } from './OpenAllowList';
11
12
  import { SimpleAllowList } from './SimpleAllowList';
12
13
  import { SimpleDenyList } from './SimpleDenyList';
@@ -45,11 +46,13 @@ export const AllowListByComponentInterface = {
45
46
  export async function allowListFromAddress(
46
47
  options: DeployableOptions,
47
48
  address: Address,
49
+ params?: ReadParams,
48
50
  ) {
49
51
  const interfaceId = (await readContract(options.config, {
50
52
  abi: aAllowListAbi,
51
53
  functionName: 'getComponentInterface',
52
54
  address,
55
+ ...params,
53
56
  })) as keyof typeof AllowListByComponentInterface;
54
57
  const Ctor = AllowListByComponentInterface[interfaceId];
55
58
  if (!Ctor) {
package/src/BoostCore.ts CHANGED
@@ -223,6 +223,10 @@ export interface BoostCoreOptionsWithPayload extends DeployableOptions {
223
223
  * @type {Address}
224
224
  */
225
225
  protocolFeeReceiver: Address;
226
+ /**
227
+ * The address that will be defined as the BoostCore owner.
228
+ */
229
+ owner: Address;
226
230
  }
227
231
 
228
232
  /**
@@ -233,7 +237,7 @@ export interface BoostCoreOptionsWithPayload extends DeployableOptions {
233
237
  */
234
238
  // biome-ignore lint/suspicious/noExplicitAny: type guard
235
239
  function isBoostCoreDeployable(opts: any): opts is BoostCoreOptionsWithPayload {
236
- return opts.registryAddress && opts.protocolFeeReceiver;
240
+ return opts.registryAddress && opts.protocolFeeReceiver && opts.owner;
237
241
  }
238
242
 
239
243
  /**
@@ -269,10 +273,10 @@ export type CreateBoostPayload = {
269
273
  * @export
270
274
  * @class BoostCore
271
275
  * @typedef {BoostCore}
272
- * @extends {Deployable<[Address, Address]>}
276
+ * @extends {Deployable<[Address, Address, Address]>}
273
277
  */
274
278
  export class BoostCore extends Deployable<
275
- [Address, Address],
279
+ [Address, Address, Address],
276
280
  typeof boostCoreAbi
277
281
  > {
278
282
  /**
@@ -302,7 +306,7 @@ export class BoostCore extends Deployable<
302
306
  * @param {BoostCoreConfig} param0
303
307
  * @param {Config} param0.config
304
308
  * @param {?Account} [param0.account]
305
- * @param {({ address?: Address; } | { registryAddress: Address; protocolFeeReceiver: Address; })} param0....options
309
+ * @param {({ address?: Address; } | { registryAddress: Address; protocolFeeReceiver: Address; owner: Address; })} param0....options
306
310
  */
307
311
  constructor({ config, account, ...options }: BoostCoreConfig) {
308
312
  if (isBoostCoreDeployed(options) && options.address) {
@@ -311,6 +315,7 @@ export class BoostCore extends Deployable<
311
315
  super({ account, config }, [
312
316
  options.registryAddress,
313
317
  options.protocolFeeReceiver,
318
+ options.owner,
314
319
  ]);
315
320
  } else {
316
321
  const { address } = assertValidAddressByChainId(
@@ -805,13 +810,13 @@ export class BoostCore extends Deployable<
805
810
  };
806
811
  const [action, budget, validator, allowList, incentives] =
807
812
  await Promise.all([
808
- actionFromAddress(options, boostPayload.action),
809
- budgetFromAddress(options, boostPayload.budget),
810
- validatorFromAddress(options, boostPayload.validator),
811
- allowListFromAddress(options, boostPayload.allowList),
813
+ actionFromAddress(options, boostPayload.action, params),
814
+ budgetFromAddress(options, boostPayload.budget, params),
815
+ validatorFromAddress(options, boostPayload.validator, params),
816
+ allowListFromAddress(options, boostPayload.allowList, params),
812
817
  Promise.all(
813
818
  boostPayload.incentives.map((incentiveAddress) =>
814
- incentiveFromAddress(options, incentiveAddress),
819
+ incentiveFromAddress(options, incentiveAddress, params),
815
820
  ),
816
821
  ),
817
822
  ]);
@@ -1498,12 +1503,12 @@ export class BoostCore extends Deployable<
1498
1503
  * @inheritdoc
1499
1504
  *
1500
1505
  * @public
1501
- * @param {?[Address, Address]} [_payload]
1506
+ * @param {?[Address, Address, Address]} [_payload]
1502
1507
  * @param {?DeployableOptions} [_options]
1503
1508
  * @returns {GenericDeployableParams}
1504
1509
  */
1505
1510
  public override buildParameters(
1506
- _payload?: [Address, Address],
1511
+ _payload?: [Address, Address, Address],
1507
1512
  _options?: DeployableOptions,
1508
1513
  ): GenericDeployableParams {
1509
1514
  const [payload, options] = this.validateDeploymentConfig(
@@ -7,6 +7,7 @@ import { readContract } from '@wagmi/core';
7
7
  import type { Address, Hex } from 'viem';
8
8
  import type { DeployableOptions } from '../Deployable/Deployable';
9
9
  import { InvalidComponentInterfaceError } from '../errors';
10
+ import type { ReadParams } from '../utils';
10
11
  import { ManagedBudget } from './ManagedBudget';
11
12
  import { ManagedBudgetWithFees } from './ManagedBudgetWithFees';
12
13
 
@@ -48,11 +49,13 @@ export const BudgetByComponentInterface = {
48
49
  export async function budgetFromAddress(
49
50
  options: DeployableOptions,
50
51
  address: Address,
52
+ params?: ReadParams,
51
53
  ) {
52
54
  const interfaceId = (await readContract(options.config, {
53
55
  abi: aBudgetAbi,
54
56
  functionName: 'getComponentInterface',
55
57
  address,
58
+ ...params,
56
59
  })) as keyof typeof BudgetByComponentInterface;
57
60
  const Ctor = BudgetByComponentInterface[interfaceId];
58
61
  if (!Ctor) {
@@ -8,6 +8,11 @@ import {
8
8
  freshManagedBudget,
9
9
  } from '@boostxyz/test/helpers';
10
10
  import { Roles } from './DeployableTargetWithRBAC';
11
+ import { createTestClient, http, zeroAddress, publicActions, walletActions } from 'viem';
12
+ import { setupConfig } from '@boostxyz/test/viem';
13
+ import { privateKeyToAccount } from 'viem/accounts';
14
+ import { hardhat } from 'viem/chains';
15
+ import { ManagedBudget } from '../Budgets/ManagedBudget';
11
16
 
12
17
  let fixtures: Fixtures;
13
18
 
@@ -100,4 +105,174 @@ describe('RBAC', () => {
100
105
  expect(await budget.isAuthorized(user)).toBe(false);
101
106
  expect(await budget.rolesOf(user)).not.toContain(Roles.MANAGER);
102
107
  });
108
+
109
+ test('can transfer ownership', async () => {
110
+ const budget = await loadFixture(freshManagedBudget(defaultOptions, fixtures));
111
+ const oldOwner = accounts[0].account;
112
+ const newOwner = accounts[9].account;
113
+ expect(await budget.owner()).toBe(oldOwner);
114
+
115
+ // Transfer ownership
116
+ await budget.transferOwnership(newOwner);
117
+
118
+ // Verify the new owner
119
+ expect(await budget.owner()).toBe(newOwner);
120
+ });
121
+
122
+ test('can renounce ownership', async () => {
123
+ const budget = await loadFixture(freshManagedBudget(defaultOptions, fixtures));
124
+ const owner = accounts[0].account;
125
+
126
+ // Verify initial owner
127
+ expect(await budget.owner()).toBe(owner);
128
+
129
+ // Renounce ownership
130
+ await budget.renounceOwnership();
131
+ const newOwner = await budget.owner();
132
+ expect(newOwner).toBe(zeroAddress);
133
+ });
134
+
135
+ test('supports two-step ownership handover', async () => {
136
+ const budget = await loadFixture(freshManagedBudget(defaultOptions, fixtures));
137
+ const currentOwner = accounts[0].account;
138
+ const newOwner = accounts[6];
139
+
140
+ const walletClient = createTestClient({
141
+ transport: http('http://127.0.0.1:8545', { retryCount: 0 }),
142
+ chain: hardhat,
143
+ mode: 'hardhat',
144
+ account: privateKeyToAccount(newOwner.key),
145
+ key: newOwner.key,
146
+ })
147
+ .extend(publicActions)
148
+ .extend(walletActions) as any;
149
+
150
+ const newOwnerOptions = {
151
+ account: privateKeyToAccount(newOwner.key),
152
+ config: setupConfig(walletClient)
153
+ };
154
+
155
+ // Create budget instance with different signer
156
+ const sameBudgetDifferentSigner = new ManagedBudget(
157
+ { config: newOwnerOptions.config, account: newOwnerOptions.account },
158
+ budget.address
159
+ );
160
+
161
+ await sameBudgetDifferentSigner.requestOwnershipHandover();
162
+
163
+ // Verify initial ownership
164
+ expect(await budget.owner()).toBe(currentOwner);
165
+ expect(await sameBudgetDifferentSigner.owner()).toBe(currentOwner);
166
+
167
+ // Complete handover from current owner
168
+ await budget.completeOwnershipHandover(newOwner.account);
169
+
170
+ // Verify ownership has transferred
171
+ expect(await budget.owner()).toBe(newOwner.account);
172
+ expect(await sameBudgetDifferentSigner.owner()).toBe(newOwner.account);
173
+ });
174
+
175
+ test('ownership handover fails if not requested', async () => {
176
+ const budget = await loadFixture(freshManagedBudget(defaultOptions, fixtures));
177
+ const newOwner = accounts[7].account;
178
+
179
+ // Try to complete handover without request
180
+ await expect(
181
+ budget.completeOwnershipHandover(newOwner)
182
+ ).rejects.toThrowError('NoHandoverRequest');
183
+ });
184
+
185
+ test('can cancel ownership handover', async () => {
186
+ const budget = await loadFixture(freshManagedBudget(defaultOptions, fixtures));
187
+ const currentOwner = accounts[0].account;
188
+ const newOwner = accounts[6];
189
+
190
+ // Create new options with new owner's account and wallet client
191
+ const walletClient = createTestClient({
192
+ transport: http('http://127.0.0.1:8545', { retryCount: 0 }),
193
+ chain: hardhat,
194
+ mode: 'hardhat',
195
+ account: privateKeyToAccount(newOwner.key),
196
+ key: newOwner.key,
197
+ })
198
+ .extend(publicActions)
199
+ .extend(walletActions) as any;
200
+
201
+ const newOwnerOptions = {
202
+ account: privateKeyToAccount(newOwner.key),
203
+ config: setupConfig(walletClient)
204
+ };
205
+
206
+ // Create budget instance with different signer
207
+ const sameBudgetDifferentSigner = new ManagedBudget(
208
+ { config: newOwnerOptions.config, account: newOwnerOptions.account },
209
+ budget.address
210
+ );
211
+
212
+ // Request handover from new owner account
213
+ await sameBudgetDifferentSigner.requestOwnershipHandover();
214
+
215
+ // Cancel the handover request
216
+ await sameBudgetDifferentSigner.cancelOwnershipHandover();
217
+
218
+ // Verify handover can't be completed after cancellation
219
+ await expect(
220
+ budget.completeOwnershipHandover(newOwner.account)
221
+ ).rejects.toThrowError('NoHandoverRequest');
222
+
223
+ // Verify ownership hasn't changed
224
+ expect(await budget.owner()).toBe(currentOwner);
225
+ });
226
+
227
+ test('can check ownership handover expiry', async () => {
228
+ const budget = await loadFixture(freshManagedBudget(defaultOptions, fixtures));
229
+ const newOwner = accounts[6];
230
+
231
+ const walletClient = createTestClient({
232
+ transport: http('http://127.0.0.1:8545', { retryCount: 0 }),
233
+ chain: hardhat,
234
+ mode: 'hardhat',
235
+ account: privateKeyToAccount(newOwner.key),
236
+ key: newOwner.key,
237
+ })
238
+ .extend(publicActions)
239
+ .extend(walletActions) as any;
240
+
241
+ const newOwnerOptions = {
242
+ account: privateKeyToAccount(newOwner.key),
243
+ config: setupConfig(walletClient)
244
+ };
245
+
246
+ // Create identical budget instance with different signer
247
+ const sameBudgetDifferentSigner = new ManagedBudget(
248
+ { config: newOwnerOptions.config, account: newOwnerOptions.account },
249
+ budget.address
250
+ );
251
+
252
+ // Check expiry before request (should be 0)
253
+ expect(await budget.ownershipHandoverExpiresAt(newOwner.account)).toBe(0n);
254
+
255
+ // Request handover
256
+ await sameBudgetDifferentSigner.requestOwnershipHandover();
257
+
258
+ // Check expiry after request (should be > 0)
259
+ const expiryTime = await budget.ownershipHandoverExpiresAt(newOwner.account);
260
+ expect(expiryTime).toBeGreaterThan(0n);
261
+
262
+ // Cancel request
263
+ await sameBudgetDifferentSigner.cancelOwnershipHandover();
264
+
265
+ // Check expiry after cancellation (should be 0 again)
266
+ expect(await budget.ownershipHandoverExpiresAt(newOwner.account)).toBe(0n);
267
+ });
268
+
269
+ test('can renounce roles', async () => {
270
+ const budget = await loadFixture(freshManagedBudget(defaultOptions, fixtures));
271
+ const account = accounts[0];
272
+ const user = account.account;
273
+
274
+ expect(await budget.hasAllRoles(user, Roles.ADMIN)).toBe(true);
275
+ await budget.renounceRoles(Roles.ADMIN);
276
+ expect(await budget.hasAllRoles(user, Roles.ADMIN)).toBe(false);
277
+ });
103
278
  });