@boostxyz/sdk 0.0.0-alpha.9 → 1.1.0-alpha.23
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.cjs.map +1 -1
- package/dist/Actions/Action.js +2 -2
- package/dist/Actions/ContractAction.d.ts +11 -11
- package/dist/Actions/ContractAction.d.ts.map +1 -1
- package/dist/Actions/ERC721MintAction.d.ts +14 -14
- package/dist/Actions/ERC721MintAction.d.ts.map +1 -1
- package/dist/Actions/EventAction.cjs +1 -1
- package/dist/Actions/EventAction.cjs.map +1 -1
- package/dist/Actions/EventAction.d.ts +174 -41
- package/dist/Actions/EventAction.d.ts.map +1 -1
- package/dist/Actions/EventAction.js +557 -129
- package/dist/Actions/EventAction.js.map +1 -1
- package/dist/AllowLists/AllowList.cjs +1 -1
- package/dist/AllowLists/AllowList.cjs.map +1 -1
- package/dist/AllowLists/AllowList.d.ts +6 -4
- package/dist/AllowLists/AllowList.d.ts.map +1 -1
- package/dist/AllowLists/AllowList.js +45 -23
- package/dist/AllowLists/AllowList.js.map +1 -1
- package/dist/AllowLists/OpenAllowList.d.ts +423 -0
- package/dist/AllowLists/OpenAllowList.d.ts.map +1 -0
- package/dist/AllowLists/SimpleAllowList.cjs +1 -1
- package/dist/AllowLists/SimpleAllowList.cjs.map +1 -1
- package/dist/AllowLists/SimpleAllowList.d.ts +92 -37
- package/dist/AllowLists/SimpleAllowList.d.ts.map +1 -1
- package/dist/AllowLists/SimpleAllowList.js +60 -75
- package/dist/AllowLists/SimpleAllowList.js.map +1 -1
- package/dist/AllowLists/SimpleDenyList.cjs +1 -1
- package/dist/AllowLists/SimpleDenyList.cjs.map +1 -1
- package/dist/AllowLists/SimpleDenyList.d.ts +203 -11
- package/dist/AllowLists/SimpleDenyList.d.ts.map +1 -1
- package/dist/AllowLists/SimpleDenyList.js +11 -112
- package/dist/AllowLists/SimpleDenyList.js.map +1 -1
- package/dist/Auth/PassthroughAuth.cjs +1 -1
- package/dist/Auth/PassthroughAuth.js +1 -1
- package/dist/Boost.cjs +1 -1
- package/dist/Boost.cjs.map +1 -1
- package/dist/Boost.d.ts +20 -21
- package/dist/Boost.d.ts.map +1 -1
- package/dist/Boost.js +43 -57
- package/dist/Boost.js.map +1 -1
- package/dist/BoostCore-Btl5BdAs.cjs +3 -0
- package/dist/BoostCore-Btl5BdAs.cjs.map +1 -0
- package/dist/BoostCore-CD56zbYX.js +2641 -0
- package/dist/BoostCore-CD56zbYX.js.map +1 -0
- package/dist/BoostCore.cjs +1 -2
- package/dist/BoostCore.cjs.map +1 -1
- package/dist/BoostCore.d.ts +749 -78
- package/dist/BoostCore.d.ts.map +1 -1
- package/dist/BoostCore.js +29 -1150
- package/dist/BoostCore.js.map +1 -1
- package/dist/BoostRegistry.cjs +1 -1
- package/dist/BoostRegistry.cjs.map +1 -1
- package/dist/BoostRegistry.d.ts +80 -25
- package/dist/BoostRegistry.d.ts.map +1 -1
- package/dist/BoostRegistry.js +164 -82
- package/dist/BoostRegistry.js.map +1 -1
- package/dist/Budgets/Budget.cjs +1 -1
- package/dist/Budgets/Budget.cjs.map +1 -1
- package/dist/Budgets/Budget.d.ts.map +1 -1
- package/dist/Budgets/Budget.js +2 -2
- package/dist/Budgets/Budget.js.map +1 -1
- package/dist/Budgets/ManagedBudget.cjs +1 -1
- package/dist/Budgets/ManagedBudget.cjs.map +1 -1
- package/dist/Budgets/ManagedBudget.d.ts +103 -221
- package/dist/Budgets/ManagedBudget.d.ts.map +1 -1
- package/dist/Budgets/ManagedBudget.js +81 -298
- package/dist/Budgets/ManagedBudget.js.map +1 -1
- package/dist/Budgets/VestingBudget.d.ts +223 -89
- package/dist/Budgets/VestingBudget.d.ts.map +1 -1
- package/dist/Deployable/Contract.cjs +1 -1
- package/dist/Deployable/Contract.cjs.map +1 -1
- package/dist/Deployable/Contract.d.ts +4 -5
- package/dist/Deployable/Contract.d.ts.map +1 -1
- package/dist/Deployable/Contract.js +5 -7
- package/dist/Deployable/Contract.js.map +1 -1
- package/dist/Deployable/Deployable.cjs.map +1 -1
- package/dist/Deployable/Deployable.d.ts +1 -1
- package/dist/Deployable/Deployable.d.ts.map +1 -1
- package/dist/Deployable/Deployable.js +3 -5
- package/dist/Deployable/Deployable.js.map +1 -1
- package/dist/Deployable/DeployableTarget.cjs +1 -1
- package/dist/Deployable/DeployableTarget.cjs.map +1 -1
- package/dist/Deployable/DeployableTarget.d.ts +13 -13
- package/dist/Deployable/DeployableTarget.d.ts.map +1 -1
- package/dist/Deployable/DeployableTarget.js +28 -25
- package/dist/Deployable/DeployableTarget.js.map +1 -1
- package/dist/Deployable/DeployableTargetWithRBAC.cjs +2 -0
- package/dist/Deployable/DeployableTargetWithRBAC.cjs.map +1 -0
- package/dist/Deployable/DeployableTargetWithRBAC.d.ts +248 -0
- package/dist/Deployable/DeployableTargetWithRBAC.d.ts.map +1 -0
- package/dist/Deployable/DeployableTargetWithRBAC.js +320 -0
- package/dist/Deployable/DeployableTargetWithRBAC.js.map +1 -0
- package/dist/Incentive-CcnOIc8L.cjs +2 -0
- package/dist/Incentive-CcnOIc8L.cjs.map +1 -0
- package/dist/Incentive-rM5nKznp.js +313 -0
- package/dist/Incentive-rM5nKznp.js.map +1 -0
- package/dist/Incentives/AllowListIncentive.cjs +1 -1
- package/dist/Incentives/AllowListIncentive.cjs.map +1 -1
- package/dist/Incentives/AllowListIncentive.d.ts +38 -16
- package/dist/Incentives/AllowListIncentive.d.ts.map +1 -1
- package/dist/Incentives/AllowListIncentive.js +43 -29
- package/dist/Incentives/AllowListIncentive.js.map +1 -1
- package/dist/Incentives/CGDAIncentive.cjs +1 -1
- package/dist/Incentives/CGDAIncentive.cjs.map +1 -1
- package/dist/Incentives/CGDAIncentive.d.ts +234 -21
- package/dist/Incentives/CGDAIncentive.d.ts.map +1 -1
- package/dist/Incentives/CGDAIncentive.js +46 -32
- package/dist/Incentives/CGDAIncentive.js.map +1 -1
- package/dist/Incentives/ERC1155Incentive.d.ts +224 -37
- package/dist/Incentives/ERC1155Incentive.d.ts.map +1 -1
- package/dist/Incentives/ERC20Incentive.cjs +1 -1
- package/dist/Incentives/ERC20Incentive.cjs.map +1 -1
- package/dist/Incentives/ERC20Incentive.d.ts +234 -30
- package/dist/Incentives/ERC20Incentive.d.ts.map +1 -1
- package/dist/Incentives/ERC20Incentive.js +62 -46
- package/dist/Incentives/ERC20Incentive.js.map +1 -1
- package/dist/{Budgets/SimpleBudget.d.ts → Incentives/ERC20VariableCriteriaIncentive.d.ts} +333 -438
- package/dist/Incentives/ERC20VariableCriteriaIncentive.d.ts.map +1 -0
- package/dist/Incentives/ERC20VariableIncentive.d.ts +231 -29
- package/dist/Incentives/ERC20VariableIncentive.d.ts.map +1 -1
- package/dist/Incentives/Incentive.cjs +1 -1
- package/dist/Incentives/Incentive.cjs.map +1 -1
- package/dist/Incentives/Incentive.d.ts +4 -4
- package/dist/Incentives/Incentive.d.ts.map +1 -1
- package/dist/Incentives/Incentive.js +16 -296
- package/dist/Incentives/Incentive.js.map +1 -1
- package/dist/Incentives/PointsIncentive.cjs +1 -1
- package/dist/Incentives/PointsIncentive.cjs.map +1 -1
- package/dist/Incentives/PointsIncentive.d.ts +40 -18
- package/dist/Incentives/PointsIncentive.d.ts.map +1 -1
- package/dist/Incentives/PointsIncentive.js +38 -24
- package/dist/Incentives/PointsIncentive.js.map +1 -1
- package/dist/SimpleDenyList-BDXpY74P.js +133 -0
- package/dist/SimpleDenyList-BDXpY74P.js.map +1 -0
- package/dist/SimpleDenyList-DNj5qDWM.cjs +2 -0
- package/dist/SimpleDenyList-DNj5qDWM.cjs.map +1 -0
- package/dist/Validators/SignerValidator.cjs +1 -1
- package/dist/Validators/SignerValidator.cjs.map +1 -1
- package/dist/Validators/SignerValidator.d.ts +16 -16
- package/dist/Validators/SignerValidator.d.ts.map +1 -1
- package/dist/Validators/SignerValidator.js +32 -28
- package/dist/Validators/SignerValidator.js.map +1 -1
- package/dist/Validators/Validator.cjs +1 -1
- package/dist/Validators/Validator.cjs.map +1 -1
- package/dist/Validators/Validator.d.ts +1 -1
- package/dist/Validators/Validator.js +2 -2
- package/dist/Validators/Validator.js.map +1 -1
- package/dist/claiming.cjs.map +1 -1
- package/dist/claiming.d.ts +1 -1
- package/dist/claiming.js.map +1 -1
- package/dist/componentInterfaces-BBCFkrZv.js +14 -0
- package/dist/componentInterfaces-BBCFkrZv.js.map +1 -0
- package/dist/componentInterfaces-DRI_dQ-P.cjs +2 -0
- package/dist/componentInterfaces-DRI_dQ-P.cjs.map +1 -0
- package/dist/deployments-DF_6-7hH.cjs +2 -0
- package/dist/deployments-DF_6-7hH.cjs.map +1 -0
- package/dist/deployments-fJsWblwS.js +56 -0
- package/dist/deployments-fJsWblwS.js.map +1 -0
- package/dist/deployments.json +58 -0
- package/dist/errors.cjs +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +256 -20
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +183 -26
- package/dist/errors.js.map +1 -1
- package/dist/{generated-57_Kffpz.js → generated-CsNyWPKA.js} +3843 -2084
- package/dist/generated-CsNyWPKA.js.map +1 -0
- package/dist/generated-DHerxf1y.cjs +3 -0
- package/dist/generated-DHerxf1y.cjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +142 -108
- package/dist/index.js.map +1 -1
- package/dist/transfers.cjs.map +1 -1
- package/dist/transfers.d.ts +1 -1
- package/dist/transfers.js.map +1 -1
- package/dist/utils.cjs +1 -1
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.ts +26 -12
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +38 -23
- package/dist/utils.js.map +1 -1
- package/package.json +20 -10
- package/src/Actions/Action.test.ts +14 -13
- package/src/Actions/ContractAction.test.ts +10 -10
- package/src/Actions/ContractAction.ts +11 -12
- package/src/Actions/ERC721MintAction.test.ts +6 -6
- package/src/Actions/ERC721MintAction.ts +14 -15
- package/src/Actions/EventAction.test.ts +735 -109
- package/src/Actions/EventAction.ts +527 -88
- package/src/AllowLists/AllowList.test.ts +7 -7
- package/src/AllowLists/AllowList.ts +5 -3
- package/src/AllowLists/OpenAllowList.test.ts +40 -0
- package/src/AllowLists/OpenAllowList.ts +45 -0
- package/src/AllowLists/SimpleAllowList.test.ts +4 -4
- package/src/AllowLists/SimpleAllowList.ts +40 -61
- package/src/AllowLists/SimpleDenyList.test.ts +4 -4
- package/src/AllowLists/SimpleDenyList.ts +41 -17
- package/src/Auth/PassthroughAuth.test.ts +1 -1
- package/src/Boost.ts +21 -24
- package/src/BoostCore.test.ts +361 -306
- package/src/BoostCore.ts +403 -220
- package/src/BoostRegistry.test.ts +53 -0
- package/src/BoostRegistry.ts +161 -40
- package/src/Budgets/Budget.test.ts +2 -2
- package/src/Budgets/Budget.ts +1 -2
- package/src/Budgets/ManagedBudget.test.ts +106 -19
- package/src/Budgets/ManagedBudget.ts +49 -321
- package/src/Budgets/VestingBudget.test.ts +7 -7
- package/src/Budgets/VestingBudget.ts +36 -106
- package/src/Deployable/Contract.ts +4 -5
- package/src/Deployable/Deployable.ts +1 -1
- package/src/Deployable/DeployableTarget.ts +30 -19
- package/src/Deployable/DeployableTargetWithRBAC.test.ts +103 -0
- package/src/Deployable/DeployableTargetWithRBAC.ts +447 -0
- package/src/Incentives/AllowListIncentive.test.ts +12 -12
- package/src/Incentives/AllowListIncentive.ts +30 -15
- package/src/Incentives/CGDAIncentive.test.ts +9 -6
- package/src/Incentives/CGDAIncentive.ts +39 -18
- package/src/Incentives/ERC1155Incentive.test.ts +3 -3
- package/src/Incentives/ERC1155Incentive.ts +30 -29
- package/src/Incentives/ERC20Incentive.test.ts +9 -6
- package/src/Incentives/ERC20Incentive.ts +54 -27
- package/src/Incentives/ERC20VariableCriteriaIncentive.test.ts +184 -0
- package/src/Incentives/ERC20VariableCriteriaIncentive.ts +325 -0
- package/src/Incentives/ERC20VariableIncentive.test.ts +8 -11
- package/src/Incentives/ERC20VariableIncentive.ts +50 -26
- package/src/Incentives/Incentive.test.ts +4 -1
- package/src/Incentives/Incentive.ts +7 -6
- package/src/Incentives/PointsIncentive.test.ts +24 -25
- package/src/Incentives/PointsIncentive.ts +32 -17
- package/src/Validators/SignerValidator.test.ts +6 -6
- package/src/Validators/SignerValidator.ts +20 -17
- package/src/Validators/Validator.test.ts +2 -2
- package/src/Validators/Validator.ts +1 -1
- package/src/claiming.ts +1 -1
- package/src/errors.ts +345 -21
- package/src/index.test.ts +118 -36
- package/src/index.ts +5 -0
- package/src/transfers.ts +1 -1
- package/src/utils.test.ts +2 -2
- package/src/utils.ts +61 -12
- package/dist/Budgets/SimpleBudget.d.ts.map +0 -1
- package/dist/componentInterfaces-CKCBwG16.cjs +0 -2
- package/dist/componentInterfaces-CKCBwG16.cjs.map +0 -1
- package/dist/componentInterfaces-DYkaxBda.js +0 -13
- package/dist/componentInterfaces-DYkaxBda.js.map +0 -1
- package/dist/generated-57_Kffpz.js.map +0 -1
- package/dist/generated-wKBNvm48.cjs +0 -3
- package/dist/generated-wKBNvm48.cjs.map +0 -1
- package/src/Budgets/SimpleBudget.test.ts +0 -152
- package/src/Budgets/SimpleBudget.ts +0 -564
|
@@ -34,7 +34,7 @@ import type {
|
|
|
34
34
|
DeployableOptions,
|
|
35
35
|
GenericDeployableParams,
|
|
36
36
|
} from '../Deployable/Deployable';
|
|
37
|
-
import {
|
|
37
|
+
import { DeployableTargetWithRBAC } from '../Deployable/DeployableTargetWithRBAC';
|
|
38
38
|
import { DeployableUnknownOwnerProvidedError } from '../errors';
|
|
39
39
|
import {
|
|
40
40
|
type FungibleTransferPayload,
|
|
@@ -115,9 +115,9 @@ export type VestingBudgetLog<
|
|
|
115
115
|
* @export
|
|
116
116
|
* @class VestingBudget
|
|
117
117
|
* @typedef {VestingBudget}
|
|
118
|
-
* @extends {
|
|
118
|
+
* @extends {DeployableTargetWithRBAC<VestingBudgetPayload>}
|
|
119
119
|
*/
|
|
120
|
-
export class VestingBudget extends
|
|
120
|
+
export class VestingBudget extends DeployableTargetWithRBAC<
|
|
121
121
|
VestingBudgetPayload,
|
|
122
122
|
typeof vestingBudgetAbi
|
|
123
123
|
> {
|
|
@@ -127,10 +127,11 @@ export class VestingBudget extends DeployableTarget<
|
|
|
127
127
|
*
|
|
128
128
|
* @public
|
|
129
129
|
* @static
|
|
130
|
-
* @type {Address}
|
|
130
|
+
* @type {Record<number, Address>}
|
|
131
131
|
*/
|
|
132
|
-
public static override
|
|
133
|
-
.VITE_VESTING_BUDGET_BASE
|
|
132
|
+
public static override bases: Record<number, Address> = {
|
|
133
|
+
31337: import.meta.env.VITE_VESTING_BUDGET_BASE,
|
|
134
|
+
};
|
|
134
135
|
/**
|
|
135
136
|
* @inheritdoc
|
|
136
137
|
*
|
|
@@ -144,7 +145,7 @@ export class VestingBudget extends DeployableTarget<
|
|
|
144
145
|
* Get the owner of the budget
|
|
145
146
|
*
|
|
146
147
|
* @public
|
|
147
|
-
* @param {?ReadParams
|
|
148
|
+
* @param {?ReadParams} [params]
|
|
148
149
|
* @returns {Promise<Address>}
|
|
149
150
|
*/
|
|
150
151
|
public owner(params?: ReadParams<typeof vestingBudgetAbi, 'owner'>) {
|
|
@@ -160,8 +161,8 @@ export class VestingBudget extends DeployableTarget<
|
|
|
160
161
|
* The timestamp at which the vesting schedule begins
|
|
161
162
|
*
|
|
162
163
|
* @public
|
|
163
|
-
* @param {?ReadParams
|
|
164
|
-
* @returns {
|
|
164
|
+
* @param {?ReadParams} [params]
|
|
165
|
+
* @returns {Promise<bigint>}
|
|
165
166
|
*/
|
|
166
167
|
public start(params?: ReadParams<typeof vestingBudgetAbi, 'start'>) {
|
|
167
168
|
return readVestingBudgetStart(this._config, {
|
|
@@ -176,8 +177,8 @@ export class VestingBudget extends DeployableTarget<
|
|
|
176
177
|
* The duration of the vesting schedule (in seconds)
|
|
177
178
|
*
|
|
178
179
|
* @public
|
|
179
|
-
* @param {?ReadParams
|
|
180
|
-
* @returns {
|
|
180
|
+
* @param {?ReadParams} [params]
|
|
181
|
+
* @returns {Promise<bigint>}
|
|
181
182
|
*/
|
|
182
183
|
public duration(params?: ReadParams<typeof vestingBudgetAbi, 'duration'>) {
|
|
183
184
|
return readVestingBudgetDuration(this._config, {
|
|
@@ -192,8 +193,8 @@ export class VestingBudget extends DeployableTarget<
|
|
|
192
193
|
* The duration of the cliff period (in seconds)
|
|
193
194
|
*
|
|
194
195
|
* @public
|
|
195
|
-
* @param {?ReadParams
|
|
196
|
-
* @returns {
|
|
196
|
+
* @param {?ReadParams} [params]
|
|
197
|
+
* @returns {Promise<bigint>}
|
|
197
198
|
*/
|
|
198
199
|
public cliff(params?: ReadParams<typeof vestingBudgetAbi, 'cliff'>) {
|
|
199
200
|
return readVestingBudgetCliff(this._config, {
|
|
@@ -212,7 +213,7 @@ export class VestingBudget extends DeployableTarget<
|
|
|
212
213
|
* @public
|
|
213
214
|
* @async
|
|
214
215
|
* @param {(FungibleTransferPayload)} transfer
|
|
215
|
-
* @param {?WriteParams
|
|
216
|
+
* @param {?WriteParams} [params]
|
|
216
217
|
* @returns {Promise<boolean>} - True if the allocation was successful
|
|
217
218
|
*/
|
|
218
219
|
public async allocate(
|
|
@@ -230,8 +231,8 @@ export class VestingBudget extends DeployableTarget<
|
|
|
230
231
|
* @public
|
|
231
232
|
* @async
|
|
232
233
|
* @param {(FungibleTransferPayload)} transfer
|
|
233
|
-
* @param {?WriteParams
|
|
234
|
-
* @returns {Promise<boolean>} - True if the allocation was successful
|
|
234
|
+
* @param {?WriteParams} [params]
|
|
235
|
+
* @returns {Promise<{ hash: `0x${string}`; result: boolean; }>} - True if the allocation was successful
|
|
235
236
|
*/
|
|
236
237
|
public async allocateRaw(
|
|
237
238
|
transfer: FungibleTransferPayload,
|
|
@@ -260,7 +261,7 @@ export class VestingBudget extends DeployableTarget<
|
|
|
260
261
|
* @public
|
|
261
262
|
* @async
|
|
262
263
|
* @param {(FungibleTransferPayload)} transfer
|
|
263
|
-
* @param {?WriteParams
|
|
264
|
+
* @param {?WriteParams} [params]
|
|
264
265
|
* @returns {Promise<boolean>} - True if the request was successful
|
|
265
266
|
*/
|
|
266
267
|
public async clawback(
|
|
@@ -279,8 +280,8 @@ export class VestingBudget extends DeployableTarget<
|
|
|
279
280
|
* @public
|
|
280
281
|
* @async
|
|
281
282
|
* @param {(FungibleTransferPayload)} transfer
|
|
282
|
-
* @param {?WriteParams
|
|
283
|
-
* @returns {Promise<boolean>} - True if the request was successful
|
|
283
|
+
* @param {?WriteParams} [params]
|
|
284
|
+
* @returns {Promise<{ hash: `0x${string}`; result: boolean; }>} - True if the request was successful
|
|
284
285
|
*/
|
|
285
286
|
public async clawbackRaw(
|
|
286
287
|
transfer: FungibleTransferPayload,
|
|
@@ -307,7 +308,7 @@ export class VestingBudget extends DeployableTarget<
|
|
|
307
308
|
* @public
|
|
308
309
|
* @async
|
|
309
310
|
* @param {(FungibleTransferPayload)} transfer
|
|
310
|
-
* @param {?WriteParams
|
|
311
|
+
* @param {?WriteParams} [params]
|
|
311
312
|
* @returns {Promise<boolean>} - True if the disbursement was successful
|
|
312
313
|
*/
|
|
313
314
|
public async disburse(
|
|
@@ -324,8 +325,8 @@ export class VestingBudget extends DeployableTarget<
|
|
|
324
325
|
* @public
|
|
325
326
|
* @async
|
|
326
327
|
* @param {(FungibleTransferPayload)} transfer
|
|
327
|
-
* @param {?WriteParams
|
|
328
|
-
* @returns {Promise<boolean>} - True if the disbursement was successful
|
|
328
|
+
* @param {?WriteParams} [params]
|
|
329
|
+
* @returns {Promise<{ hash: `0x${string}`; result: boolean; }>} - True if the disbursement was successful
|
|
329
330
|
*/
|
|
330
331
|
public async disburseRaw(
|
|
331
332
|
transfer: FungibleTransferPayload,
|
|
@@ -351,7 +352,7 @@ export class VestingBudget extends DeployableTarget<
|
|
|
351
352
|
* @public
|
|
352
353
|
* @async
|
|
353
354
|
* @param {Array<FungibleTransferPayload>} transfers
|
|
354
|
-
* @param {?WriteParams
|
|
355
|
+
* @param {?WriteParams} [params]
|
|
355
356
|
* @returns {Promise<boolean>} - True if all disbursements were successful
|
|
356
357
|
*/
|
|
357
358
|
public async disburseBatch(
|
|
@@ -367,8 +368,8 @@ export class VestingBudget extends DeployableTarget<
|
|
|
367
368
|
* @public
|
|
368
369
|
* @async
|
|
369
370
|
* @param {Array<FungibleTransferPayload>} transfers
|
|
370
|
-
* @param {?WriteParams
|
|
371
|
-
* @returns {Promise<boolean>} - True if all disbursements were successful
|
|
371
|
+
* @param {?WriteParams} [params]
|
|
372
|
+
* @returns {Promise<{ hash: `0x${string}`; result: boolean; }>} - True if all disbursements were successful
|
|
372
373
|
*/
|
|
373
374
|
public async disburseBatchRaw(
|
|
374
375
|
transfers: FungibleTransferPayload[],
|
|
@@ -388,82 +389,11 @@ export class VestingBudget extends DeployableTarget<
|
|
|
388
389
|
return { hash, result };
|
|
389
390
|
}
|
|
390
391
|
|
|
391
|
-
/**
|
|
392
|
-
* Set the authorized status of the given accounts
|
|
393
|
-
* The mechanism for managing authorization is left to the implementing contract
|
|
394
|
-
*
|
|
395
|
-
* @public
|
|
396
|
-
* @async
|
|
397
|
-
* @param {Address[]} addresses - The accounts to authorize or deauthorize
|
|
398
|
-
* @param {boolean[]} allowed - The authorization status for the given accounts
|
|
399
|
-
* @param {?WriteParams<typeof vestingBudgetAbi, 'setAuthorized'>} [params]
|
|
400
|
-
* @returns {Promise<void>}
|
|
401
|
-
*/
|
|
402
|
-
public async setAuthorized(
|
|
403
|
-
addresses: Address[],
|
|
404
|
-
allowed: boolean[],
|
|
405
|
-
params?: WriteParams<typeof vestingBudgetAbi, 'setAuthorized'>,
|
|
406
|
-
) {
|
|
407
|
-
return await this.awaitResult(
|
|
408
|
-
this.setAuthorizedRaw(addresses, allowed, params),
|
|
409
|
-
);
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* Set the authorized status of the given accounts
|
|
414
|
-
* The mechanism for managing authorization is left to the implementing contract
|
|
415
|
-
*
|
|
416
|
-
* @public
|
|
417
|
-
* @async
|
|
418
|
-
* @param {Address[]} addresses - The accounts to authorize or deauthorize
|
|
419
|
-
* @param {boolean[]} allowed - The authorization status for the given accounts
|
|
420
|
-
* @param {?WriteParams<typeof vestingBudgetAbi, 'setAuthorized'>} [params]
|
|
421
|
-
* @returns {Promise<void>}
|
|
422
|
-
*/
|
|
423
|
-
public async setAuthorizedRaw(
|
|
424
|
-
addresses: Address[],
|
|
425
|
-
allowed: boolean[],
|
|
426
|
-
params?: WriteParams<typeof vestingBudgetAbi, 'setAuthorized'>,
|
|
427
|
-
) {
|
|
428
|
-
const { request, result } = await simulateVestingBudgetSetAuthorized(
|
|
429
|
-
this._config,
|
|
430
|
-
{
|
|
431
|
-
address: this.assertValidAddress(),
|
|
432
|
-
args: [addresses, allowed],
|
|
433
|
-
...this.optionallyAttachAccount(),
|
|
434
|
-
// biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
|
|
435
|
-
...(params as any),
|
|
436
|
-
},
|
|
437
|
-
);
|
|
438
|
-
const hash = await writeVestingBudgetSetAuthorized(this._config, request);
|
|
439
|
-
return { hash, result };
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
/**
|
|
443
|
-
* Check if the given account is authorized to use the budget
|
|
444
|
-
*
|
|
445
|
-
* @public
|
|
446
|
-
* @param {Address} account
|
|
447
|
-
* @param {?ReadParams<typeof vestingBudgetAbi, 'isAuthorized'>} [params]
|
|
448
|
-
* @returns {Promise<boolean>} - True if the account is authorized
|
|
449
|
-
*/
|
|
450
|
-
public isAuthorized(
|
|
451
|
-
account: Address,
|
|
452
|
-
params?: ReadParams<typeof vestingBudgetAbi, 'isAuthorized'>,
|
|
453
|
-
) {
|
|
454
|
-
return readVestingBudgetIsAuthorized(this._config, {
|
|
455
|
-
address: this.assertValidAddress(),
|
|
456
|
-
args: [account],
|
|
457
|
-
// biome-ignore lint/suspicious/noExplicitAny: Accept any shape of valid wagmi/viem parameters, wagmi does the same thing internally
|
|
458
|
-
...(params as any),
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
|
|
462
392
|
/**
|
|
463
393
|
* Get the end time of the vesting schedule
|
|
464
394
|
*
|
|
465
395
|
* @public
|
|
466
|
-
* @param {?ReadParams
|
|
396
|
+
* @param {?ReadParams} [params]
|
|
467
397
|
* @returns {Promise<bigint>}
|
|
468
398
|
*/
|
|
469
399
|
public end(params?: ReadParams<typeof vestingBudgetAbi, 'end'>) {
|
|
@@ -480,12 +410,12 @@ export class VestingBudget extends DeployableTarget<
|
|
|
480
410
|
* This is equal to the sum of the total current balance and the total distributed amount
|
|
481
411
|
*
|
|
482
412
|
* @public
|
|
483
|
-
* @param {Address} asset - The address of the asset (or the zero address for native assets)
|
|
484
|
-
* @param {?ReadParams
|
|
413
|
+
* @param {Address} [asset="0x0000000000000000000000000000000000000000"] - The address of the asset (or the zero address for native assets)
|
|
414
|
+
* @param {?ReadParams} [params]
|
|
485
415
|
* @returns {Promise<bigint>}
|
|
486
416
|
*/
|
|
487
417
|
public total(
|
|
488
|
-
asset: Address,
|
|
418
|
+
asset: Address = zeroAddress,
|
|
489
419
|
params?: ReadParams<typeof vestingBudgetAbi, 'total'>,
|
|
490
420
|
) {
|
|
491
421
|
return readVestingBudgetTotal(this._config, {
|
|
@@ -501,12 +431,12 @@ export class VestingBudget extends DeployableTarget<
|
|
|
501
431
|
* This is equal to the total vested amount minus any already distributed
|
|
502
432
|
*
|
|
503
433
|
* @public
|
|
504
|
-
* @param {Address} asset - The address of the asset (or the zero address for native assets)
|
|
505
|
-
* @param {?ReadParams
|
|
434
|
+
* @param {Address} [asset="0x0000000000000000000000000000000000000000"] - The address of the asset (or the zero address for native assets)
|
|
435
|
+
* @param {?ReadParams} [params]
|
|
506
436
|
* @returns {Promise<bigint>} - The amount of assets currently available for distribution
|
|
507
437
|
*/
|
|
508
438
|
public available(
|
|
509
|
-
asset: Address,
|
|
439
|
+
asset: Address = zeroAddress,
|
|
510
440
|
params?: ReadParams<typeof vestingBudgetAbi, 'available'>,
|
|
511
441
|
) {
|
|
512
442
|
return readVestingBudgetAvailable(this._config, {
|
|
@@ -521,12 +451,12 @@ export class VestingBudget extends DeployableTarget<
|
|
|
521
451
|
* Get the amount of assets that have been distributed from the budget
|
|
522
452
|
*
|
|
523
453
|
* @public
|
|
524
|
-
* @param {Address} asset
|
|
525
|
-
* @param {?ReadParams
|
|
454
|
+
* @param {Address} [asset="0x0000000000000000000000000000000000000000"]
|
|
455
|
+
* @param {?ReadParams} [params]
|
|
526
456
|
* @returns {Promise<bigint>} - The amount of assets distributed
|
|
527
457
|
*/
|
|
528
458
|
public distributed(
|
|
529
|
-
asset: Address,
|
|
459
|
+
asset: Address = zeroAddress,
|
|
530
460
|
params?: ReadParams<typeof vestingBudgetAbi, 'distributed'>,
|
|
531
461
|
) {
|
|
532
462
|
return readVestingBudgetDistributed(this._config, {
|
|
@@ -61,7 +61,7 @@ export class Contract<ContractAbi extends Abi> {
|
|
|
61
61
|
*
|
|
62
62
|
* @public
|
|
63
63
|
* @readonly
|
|
64
|
-
* @type {
|
|
64
|
+
* @type {Address | undefined}
|
|
65
65
|
*/
|
|
66
66
|
public get address() {
|
|
67
67
|
return this._address;
|
|
@@ -174,7 +174,6 @@ export class Contract<ContractAbi extends Abi> {
|
|
|
174
174
|
* A typed wrapper for `wagmi.watchContractEvent`
|
|
175
175
|
*
|
|
176
176
|
* @public
|
|
177
|
-
* @async
|
|
178
177
|
* @template {ContractEvent} event
|
|
179
178
|
* @param {(
|
|
180
179
|
* log: WatchContractEventOnLogsParameter<ContractAbi, event, true>[number],
|
|
@@ -182,9 +181,9 @@ export class Contract<ContractAbi extends Abi> {
|
|
|
182
181
|
* @param {?WatchParams<ContractAbi, event> & {
|
|
183
182
|
* eventName?: event;
|
|
184
183
|
* }} [params]
|
|
185
|
-
* @returns {
|
|
184
|
+
* @returns {() => void}
|
|
186
185
|
*/
|
|
187
|
-
public
|
|
186
|
+
public subscribe<event extends ContractEventName<ContractAbi>>(
|
|
188
187
|
cb: (
|
|
189
188
|
log: WatchContractEventOnLogsParameter<ContractAbi, event, true>[number],
|
|
190
189
|
) => unknown,
|
|
@@ -218,7 +217,7 @@ export class Contract<ContractAbi extends Abi> {
|
|
|
218
217
|
* @template [Result=unknown]
|
|
219
218
|
* @param {Promise<HashAndSimulatedResult<Result>>} hashPromise
|
|
220
219
|
* @param {?Omit<WaitForTransactionReceiptParameters, 'hash'>} [waitParams]
|
|
221
|
-
* @returns {
|
|
220
|
+
* @returns {Promise<Result>}
|
|
222
221
|
*/
|
|
223
222
|
protected async awaitResult<Result = unknown>(
|
|
224
223
|
hashPromise: Promise<HashAndSimulatedResult<Result>>,
|
|
@@ -149,7 +149,7 @@ export class Deployable<
|
|
|
149
149
|
* @param {?Payload} [_payload]
|
|
150
150
|
* @param {?DeployableOptions} [_options]
|
|
151
151
|
* @param {?Omit<WaitForTransactionReceiptParameters, 'hash'>} [waitParams] - See [viem.WaitForTransactionReceipt](https://v1.viem.sh/docs/actions/public/waitForTransactionReceipt.html#waitfortransactionreceipt)
|
|
152
|
-
* @returns {
|
|
152
|
+
* @returns {Promise<this>}
|
|
153
153
|
*/
|
|
154
154
|
protected async deploy(
|
|
155
155
|
_payload?: Payload,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type aCloneableAbi,
|
|
3
|
-
readACloneableGetComponentInterface
|
|
3
|
+
readACloneableGetComponentInterface,
|
|
4
4
|
readACloneableSupportsInterface,
|
|
5
5
|
} from '@boostxyz/evm';
|
|
6
6
|
import { deployContract } from '@wagmi/core';
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
type Hex,
|
|
12
12
|
type WaitForTransactionReceiptParameters,
|
|
13
13
|
isAddress,
|
|
14
|
+
isAddressEqual,
|
|
14
15
|
zeroAddress,
|
|
15
16
|
} from 'viem';
|
|
16
17
|
import {
|
|
@@ -38,13 +39,13 @@ export class DeployableTarget<
|
|
|
38
39
|
ContractAbi extends Abi,
|
|
39
40
|
> extends Deployable<Payload, ContractAbi> {
|
|
40
41
|
/**
|
|
41
|
-
* A static property representing the address of the base implementation on chain, used when cloning base contracts.
|
|
42
|
+
* A static property representing a map of stringified chain ID's to the address of the base implementation on chain, used when cloning base contracts.
|
|
42
43
|
*
|
|
43
44
|
* @static
|
|
44
45
|
* @readonly
|
|
45
|
-
* @type {Address}
|
|
46
|
+
* @type {Record<string, Address>}
|
|
46
47
|
*/
|
|
47
|
-
static readonly
|
|
48
|
+
static readonly bases: Record<number, Address> = {};
|
|
48
49
|
/**
|
|
49
50
|
* The target's registry type.
|
|
50
51
|
*
|
|
@@ -59,9 +60,16 @@ export class DeployableTarget<
|
|
|
59
60
|
* @readonly
|
|
60
61
|
* @type {boolean}
|
|
61
62
|
*/
|
|
62
|
-
|
|
63
|
-
get isBase() {
|
|
64
|
-
if (
|
|
63
|
+
readonly _isBase: boolean = true;
|
|
64
|
+
public get isBase() {
|
|
65
|
+
if (
|
|
66
|
+
!!this.address &&
|
|
67
|
+
Object.values(this.bases).some((base) =>
|
|
68
|
+
// biome-ignore lint/style/noNonNullAssertion: won't evaluate this if address checked and defined above
|
|
69
|
+
isAddressEqual(this.address!, base),
|
|
70
|
+
)
|
|
71
|
+
)
|
|
72
|
+
return true;
|
|
65
73
|
return this._isBase;
|
|
66
74
|
}
|
|
67
75
|
|
|
@@ -75,7 +83,7 @@ export class DeployableTarget<
|
|
|
75
83
|
*/
|
|
76
84
|
constructor(
|
|
77
85
|
options: DeployableOptions,
|
|
78
|
-
payload
|
|
86
|
+
payload?: DeployablePayloadOrAddress<Payload>,
|
|
79
87
|
isBase?: boolean,
|
|
80
88
|
) {
|
|
81
89
|
super(options, payload);
|
|
@@ -83,22 +91,25 @@ export class DeployableTarget<
|
|
|
83
91
|
if (
|
|
84
92
|
typeof payload === 'string' &&
|
|
85
93
|
isAddress(payload) &&
|
|
86
|
-
payload !==
|
|
87
|
-
|
|
94
|
+
payload !== zeroAddress &&
|
|
95
|
+
!Object.values(this.bases).some((base) => {
|
|
96
|
+
if (!payload || !base) return false;
|
|
97
|
+
return isAddressEqual(payload, base);
|
|
98
|
+
})
|
|
88
99
|
)
|
|
89
100
|
isBase = false;
|
|
90
101
|
if (isBase !== undefined) this._isBase = isBase;
|
|
91
102
|
}
|
|
92
103
|
|
|
93
104
|
/**
|
|
94
|
-
* A getter that will return the base implementation's static
|
|
105
|
+
* A getter that will return the base implementation's static addresses by numerical chain ID
|
|
95
106
|
*
|
|
96
107
|
* @public
|
|
97
108
|
* @readonly
|
|
98
|
-
* @type {Address}
|
|
109
|
+
* @type {Record<number, Address>}
|
|
99
110
|
*/
|
|
100
|
-
public get
|
|
101
|
-
return (this.constructor as typeof DeployableTarget).
|
|
111
|
+
public get bases(): Record<number, Address> {
|
|
112
|
+
return (this.constructor as typeof DeployableTarget).bases;
|
|
102
113
|
}
|
|
103
114
|
|
|
104
115
|
/**
|
|
@@ -120,7 +131,7 @@ export class DeployableTarget<
|
|
|
120
131
|
* @param {?Payload} [payload]
|
|
121
132
|
* @param {?DeployableOptions} [options]
|
|
122
133
|
* @param {?Omit<WaitForTransactionReceiptParameters, 'hash'>} [waitParams]
|
|
123
|
-
* @returns {
|
|
134
|
+
* @returns {Promise<this>}
|
|
124
135
|
*/
|
|
125
136
|
protected override async deploy(
|
|
126
137
|
payload?: Payload,
|
|
@@ -163,8 +174,8 @@ export class DeployableTarget<
|
|
|
163
174
|
* @public
|
|
164
175
|
* @async
|
|
165
176
|
* @param {Hex} interfaceId - The interface identifier
|
|
166
|
-
* @param {?ReadParams
|
|
167
|
-
* @returns {
|
|
177
|
+
* @param {?ReadParams} [params]
|
|
178
|
+
* @returns {Promise<boolean>} - True if the contract supports the interface
|
|
168
179
|
*/
|
|
169
180
|
public async supportsInterface(
|
|
170
181
|
interfaceId: Hex,
|
|
@@ -185,8 +196,8 @@ export class DeployableTarget<
|
|
|
185
196
|
*
|
|
186
197
|
* @public
|
|
187
198
|
* @async
|
|
188
|
-
* @param {?ReadParams
|
|
189
|
-
* @returns {
|
|
199
|
+
* @param {?ReadParams} [params]
|
|
200
|
+
* @returns {Promise<Hex>}
|
|
190
201
|
*/
|
|
191
202
|
public async getComponentInterface(
|
|
192
203
|
params?: ReadParams<typeof aCloneableAbi, 'getComponentInterface'>,
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
|
|
2
|
+
import { beforeAll, describe, expect, test } from 'vitest';
|
|
3
|
+
import { accounts } from '@boostxyz/test/accounts';
|
|
4
|
+
import {
|
|
5
|
+
type Fixtures,
|
|
6
|
+
defaultOptions,
|
|
7
|
+
deployFixtures,
|
|
8
|
+
freshManagedBudget,
|
|
9
|
+
} from '@boostxyz/test/helpers';
|
|
10
|
+
import { Roles } from './DeployableTargetWithRBAC';
|
|
11
|
+
|
|
12
|
+
let fixtures: Fixtures;
|
|
13
|
+
|
|
14
|
+
beforeAll(async () => {
|
|
15
|
+
fixtures = await loadFixture(deployFixtures(defaultOptions));
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe('RBAC', () => {
|
|
19
|
+
test('can grant roles', async () => {
|
|
20
|
+
const budget = await loadFixture(freshManagedBudget(defaultOptions, fixtures));
|
|
21
|
+
const manager = accounts[0].account;
|
|
22
|
+
expect(await budget.rolesOf(manager)).not.toContain(Roles.MANAGER);
|
|
23
|
+
await budget.grantRoles(manager, Roles.MANAGER);
|
|
24
|
+
expect(await budget.rolesOf(manager)).toContain(Roles.MANAGER);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('can revoke roles', async () => {
|
|
28
|
+
const budget = await loadFixture(freshManagedBudget(defaultOptions, fixtures));
|
|
29
|
+
const admin = accounts[1].account;
|
|
30
|
+
await budget.grantRoles(admin, Roles.ADMIN);
|
|
31
|
+
expect(await budget.rolesOf(admin)).toContain(Roles.ADMIN);
|
|
32
|
+
await budget.revokeRoles(admin, Roles.ADMIN);
|
|
33
|
+
expect(await budget.rolesOf(admin)).not.toContain(Roles.ADMIN);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test('can grant many roles', async () => {
|
|
37
|
+
const budget = await loadFixture(freshManagedBudget(defaultOptions, fixtures));
|
|
38
|
+
const admin = accounts[2].account;
|
|
39
|
+
const manager = accounts[3].account;
|
|
40
|
+
await budget.grantManyRoles(
|
|
41
|
+
[admin, manager],
|
|
42
|
+
[Roles.ADMIN, Roles.MANAGER],
|
|
43
|
+
);
|
|
44
|
+
expect(await budget.hasAllRoles(admin, Roles.ADMIN)).toBe(true);
|
|
45
|
+
expect(await budget.hasAllRoles(manager, Roles.MANAGER)).toBe(true);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('can revoke many roles', async () => {
|
|
49
|
+
const budget = await loadFixture(freshManagedBudget(defaultOptions, fixtures));
|
|
50
|
+
const admin = accounts[4].account;
|
|
51
|
+
const manager = accounts[5].account;
|
|
52
|
+
await budget.grantManyRoles(
|
|
53
|
+
[admin, manager],
|
|
54
|
+
[Roles.ADMIN, Roles.MANAGER],
|
|
55
|
+
);
|
|
56
|
+
expect(await budget.hasAllRoles(admin, Roles.ADMIN)).toBe(true);
|
|
57
|
+
expect(await budget.hasAllRoles(manager, Roles.MANAGER)).toBe(true);
|
|
58
|
+
await budget.revokeManyRoles(
|
|
59
|
+
[admin, manager],
|
|
60
|
+
[Roles.ADMIN, Roles.MANAGER],
|
|
61
|
+
);
|
|
62
|
+
expect(await budget.hasAllRoles(admin, Roles.ADMIN)).toBe(false);
|
|
63
|
+
expect(await budget.hasAllRoles(manager, Roles.MANAGER)).toBe(false);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('can check for any role', async () => {
|
|
67
|
+
const budget = await loadFixture(freshManagedBudget(defaultOptions, fixtures));
|
|
68
|
+
const user = accounts[6].account;
|
|
69
|
+
expect(await budget.hasAnyRole(user, Roles.MANAGER | Roles.ADMIN)).toBe(false);
|
|
70
|
+
await budget.grantRoles(user, Roles.MANAGER);
|
|
71
|
+
expect(await budget.hasAnyRole(user, Roles.MANAGER | Roles.ADMIN)).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('can check for all roles', async () => {
|
|
75
|
+
const budget = await loadFixture(freshManagedBudget(defaultOptions, fixtures));
|
|
76
|
+
const user = accounts[7].account;
|
|
77
|
+
await budget.grantRoles(user, Roles.MANAGER);
|
|
78
|
+
expect(await budget.hasAllRoles(user, Roles.MANAGER | Roles.ADMIN)).toBe(false);
|
|
79
|
+
await budget.grantRoles(user, Roles.ADMIN);
|
|
80
|
+
expect(await budget.hasAllRoles(user, Roles.MANAGER | Roles.ADMIN)).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('can get roles of an account', async () => {
|
|
84
|
+
const budget = await loadFixture(freshManagedBudget(defaultOptions, fixtures));
|
|
85
|
+
const user = accounts[8].account;
|
|
86
|
+
await budget.grantRoles(user, Roles.MANAGER | Roles.ADMIN);
|
|
87
|
+
const roles = await budget.rolesOf(user);
|
|
88
|
+
expect(roles).toContain(Roles.MANAGER);
|
|
89
|
+
expect(roles).toContain(Roles.ADMIN);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('can set and check authorization', async () => {
|
|
93
|
+
const budget = await loadFixture(freshManagedBudget(defaultOptions, fixtures));
|
|
94
|
+
const user = accounts[9].account;
|
|
95
|
+
expect(await budget.rolesOf(user)).not.toContain(Roles.MANAGER);
|
|
96
|
+
await budget.setAuthorized([user], [true]);
|
|
97
|
+
expect(await budget.isAuthorized(user)).toBe(true);
|
|
98
|
+
expect(await budget.rolesOf(user)).toContain(Roles.MANAGER);
|
|
99
|
+
await budget.setAuthorized([user], [false]);
|
|
100
|
+
expect(await budget.isAuthorized(user)).toBe(false);
|
|
101
|
+
expect(await budget.rolesOf(user)).not.toContain(Roles.MANAGER);
|
|
102
|
+
});
|
|
103
|
+
});
|