@bloxchain/contracts 1.0.0-alpha

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 (34) hide show
  1. package/README.md +49 -0
  2. package/abi/BareBlox.abi.json +1341 -0
  3. package/abi/BaseStateMachine.abi.json +1308 -0
  4. package/abi/ControlBlox.abi.json +6210 -0
  5. package/abi/EngineBlox.abi.json +872 -0
  6. package/abi/GuardController.abi.json +3045 -0
  7. package/abi/IDefinition.abi.json +94 -0
  8. package/abi/RoleBlox.abi.json +4569 -0
  9. package/abi/RuntimeRBAC.abi.json +1857 -0
  10. package/abi/RuntimeRBACDefinitions.abi.json +133 -0
  11. package/abi/SecureBlox.abi.json +4085 -0
  12. package/abi/SecureOwnable.abi.json +4085 -0
  13. package/abi/SecureOwnableDefinitions.abi.json +354 -0
  14. package/abi/SimpleRWA20.abi.json +5545 -0
  15. package/abi/SimpleRWA20Definitions.abi.json +172 -0
  16. package/abi/SimpleVault.abi.json +5208 -0
  17. package/abi/SimpleVaultDefinitions.abi.json +250 -0
  18. package/contracts/core/access/RuntimeRBAC.sol +344 -0
  19. package/contracts/core/access/interface/IRuntimeRBAC.sol +108 -0
  20. package/contracts/core/access/lib/definitions/RuntimeRBACDefinitions.sol +168 -0
  21. package/contracts/core/base/BaseStateMachine.sol +834 -0
  22. package/contracts/core/base/interface/IBaseStateMachine.sol +153 -0
  23. package/contracts/core/execution/GuardController.sol +507 -0
  24. package/contracts/core/execution/interface/IGuardController.sol +120 -0
  25. package/contracts/core/execution/lib/definitions/GuardControllerDefinitions.sol +401 -0
  26. package/contracts/core/lib/EngineBlox.sol +2283 -0
  27. package/contracts/core/security/SecureOwnable.sol +419 -0
  28. package/contracts/core/security/interface/ISecureOwnable.sol +118 -0
  29. package/contracts/core/security/lib/definitions/SecureOwnableDefinitions.sol +757 -0
  30. package/contracts/interfaces/IDefinition.sol +40 -0
  31. package/contracts/interfaces/IEventForwarder.sol +33 -0
  32. package/contracts/interfaces/IOnActionHook.sol +79 -0
  33. package/contracts/utils/SharedValidation.sol +486 -0
  34. package/package.json +47 -0
@@ -0,0 +1,250 @@
1
+ [
2
+ {
3
+ "inputs": [],
4
+ "name": "APPROVE_WITHDRAWAL_DELAYED_SELECTOR",
5
+ "outputs": [
6
+ {
7
+ "internalType": "bytes4",
8
+ "name": "",
9
+ "type": "bytes4"
10
+ }
11
+ ],
12
+ "stateMutability": "view",
13
+ "type": "function"
14
+ },
15
+ {
16
+ "inputs": [],
17
+ "name": "APPROVE_WITHDRAWAL_META_SELECTOR",
18
+ "outputs": [
19
+ {
20
+ "internalType": "bytes4",
21
+ "name": "",
22
+ "type": "bytes4"
23
+ }
24
+ ],
25
+ "stateMutability": "view",
26
+ "type": "function"
27
+ },
28
+ {
29
+ "inputs": [],
30
+ "name": "CANCEL_WITHDRAWAL_SELECTOR",
31
+ "outputs": [
32
+ {
33
+ "internalType": "bytes4",
34
+ "name": "",
35
+ "type": "bytes4"
36
+ }
37
+ ],
38
+ "stateMutability": "view",
39
+ "type": "function"
40
+ },
41
+ {
42
+ "inputs": [],
43
+ "name": "GENERIC_APPROVAL",
44
+ "outputs": [
45
+ {
46
+ "internalType": "bytes32",
47
+ "name": "",
48
+ "type": "bytes32"
49
+ }
50
+ ],
51
+ "stateMutability": "view",
52
+ "type": "function"
53
+ },
54
+ {
55
+ "inputs": [],
56
+ "name": "GENERIC_CANCELLATION",
57
+ "outputs": [
58
+ {
59
+ "internalType": "bytes32",
60
+ "name": "",
61
+ "type": "bytes32"
62
+ }
63
+ ],
64
+ "stateMutability": "view",
65
+ "type": "function"
66
+ },
67
+ {
68
+ "inputs": [],
69
+ "name": "GENERIC_META_APPROVAL",
70
+ "outputs": [
71
+ {
72
+ "internalType": "bytes32",
73
+ "name": "",
74
+ "type": "bytes32"
75
+ }
76
+ ],
77
+ "stateMutability": "view",
78
+ "type": "function"
79
+ },
80
+ {
81
+ "inputs": [],
82
+ "name": "WITHDRAW_ETH",
83
+ "outputs": [
84
+ {
85
+ "internalType": "bytes32",
86
+ "name": "",
87
+ "type": "bytes32"
88
+ }
89
+ ],
90
+ "stateMutability": "view",
91
+ "type": "function"
92
+ },
93
+ {
94
+ "inputs": [],
95
+ "name": "WITHDRAW_ETH_REQUEST_SELECTOR",
96
+ "outputs": [
97
+ {
98
+ "internalType": "bytes4",
99
+ "name": "",
100
+ "type": "bytes4"
101
+ }
102
+ ],
103
+ "stateMutability": "view",
104
+ "type": "function"
105
+ },
106
+ {
107
+ "inputs": [],
108
+ "name": "WITHDRAW_ETH_SELECTOR",
109
+ "outputs": [
110
+ {
111
+ "internalType": "bytes4",
112
+ "name": "",
113
+ "type": "bytes4"
114
+ }
115
+ ],
116
+ "stateMutability": "view",
117
+ "type": "function"
118
+ },
119
+ {
120
+ "inputs": [],
121
+ "name": "WITHDRAW_TOKEN",
122
+ "outputs": [
123
+ {
124
+ "internalType": "bytes32",
125
+ "name": "",
126
+ "type": "bytes32"
127
+ }
128
+ ],
129
+ "stateMutability": "view",
130
+ "type": "function"
131
+ },
132
+ {
133
+ "inputs": [],
134
+ "name": "WITHDRAW_TOKEN_REQUEST_SELECTOR",
135
+ "outputs": [
136
+ {
137
+ "internalType": "bytes4",
138
+ "name": "",
139
+ "type": "bytes4"
140
+ }
141
+ ],
142
+ "stateMutability": "view",
143
+ "type": "function"
144
+ },
145
+ {
146
+ "inputs": [],
147
+ "name": "WITHDRAW_TOKEN_SELECTOR",
148
+ "outputs": [
149
+ {
150
+ "internalType": "bytes4",
151
+ "name": "",
152
+ "type": "bytes4"
153
+ }
154
+ ],
155
+ "stateMutability": "view",
156
+ "type": "function"
157
+ },
158
+ {
159
+ "inputs": [],
160
+ "name": "getFunctionSchemas",
161
+ "outputs": [
162
+ {
163
+ "components": [
164
+ {
165
+ "internalType": "string",
166
+ "name": "functionSignature",
167
+ "type": "string"
168
+ },
169
+ {
170
+ "internalType": "bytes4",
171
+ "name": "functionSelector",
172
+ "type": "bytes4"
173
+ },
174
+ {
175
+ "internalType": "bytes32",
176
+ "name": "operationType",
177
+ "type": "bytes32"
178
+ },
179
+ {
180
+ "internalType": "string",
181
+ "name": "operationName",
182
+ "type": "string"
183
+ },
184
+ {
185
+ "internalType": "uint16",
186
+ "name": "supportedActionsBitmap",
187
+ "type": "uint16"
188
+ },
189
+ {
190
+ "internalType": "bool",
191
+ "name": "isProtected",
192
+ "type": "bool"
193
+ },
194
+ {
195
+ "internalType": "bytes4[]",
196
+ "name": "handlerForSelectors",
197
+ "type": "bytes4[]"
198
+ }
199
+ ],
200
+ "internalType": "struct EngineBlox.FunctionSchema[]",
201
+ "name": "",
202
+ "type": "tuple[]"
203
+ }
204
+ ],
205
+ "stateMutability": "pure",
206
+ "type": "function"
207
+ },
208
+ {
209
+ "inputs": [],
210
+ "name": "getRolePermissions",
211
+ "outputs": [
212
+ {
213
+ "components": [
214
+ {
215
+ "internalType": "bytes32[]",
216
+ "name": "roleHashes",
217
+ "type": "bytes32[]"
218
+ },
219
+ {
220
+ "components": [
221
+ {
222
+ "internalType": "bytes4",
223
+ "name": "functionSelector",
224
+ "type": "bytes4"
225
+ },
226
+ {
227
+ "internalType": "uint16",
228
+ "name": "grantedActionsBitmap",
229
+ "type": "uint16"
230
+ },
231
+ {
232
+ "internalType": "bytes4[]",
233
+ "name": "handlerForSelectors",
234
+ "type": "bytes4[]"
235
+ }
236
+ ],
237
+ "internalType": "struct EngineBlox.FunctionPermission[]",
238
+ "name": "functionPermissions",
239
+ "type": "tuple[]"
240
+ }
241
+ ],
242
+ "internalType": "struct IDefinition.RolePermission",
243
+ "name": "",
244
+ "type": "tuple"
245
+ }
246
+ ],
247
+ "stateMutability": "pure",
248
+ "type": "function"
249
+ }
250
+ ]
@@ -0,0 +1,344 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ pragma solidity 0.8.33;
3
+
4
+ // Contract imports
5
+ import "../base/BaseStateMachine.sol";
6
+ import "../lib/EngineBlox.sol";
7
+ import "../../utils/SharedValidation.sol";
8
+ import "./lib/definitions/RuntimeRBACDefinitions.sol";
9
+ import "../../interfaces/IDefinition.sol";
10
+ import "./interface/IRuntimeRBAC.sol";
11
+
12
+ /**
13
+ * @title RuntimeRBAC
14
+ * @dev Minimal Runtime Role-Based Access Control system based on EngineBlox
15
+ *
16
+ * This contract provides essential runtime RBAC functionality:
17
+ * - Creation of non-protected roles
18
+ * - Basic wallet assignment to roles
19
+ * - Function permission management per role
20
+ * - Integration with EngineBlox for secure operations
21
+ *
22
+ * Key Features:
23
+ * - Only non-protected roles can be created dynamically
24
+ * - Protected roles (OWNER, BROADCASTER, RECOVERY) are managed by SecureOwnable
25
+ * - Minimal interface for core RBAC operations
26
+ * - Essential role management functions only
27
+ */
28
+ abstract contract RuntimeRBAC is BaseStateMachine {
29
+ using EngineBlox for EngineBlox.SecureOperationState;
30
+ using SharedValidation for *;
31
+
32
+ /**
33
+ * @dev Action types for batched RBAC configuration
34
+ */
35
+ enum RoleConfigActionType {
36
+ CREATE_ROLE,
37
+ REMOVE_ROLE,
38
+ ADD_WALLET,
39
+ REVOKE_WALLET,
40
+ ADD_FUNCTION_TO_ROLE,
41
+ REMOVE_FUNCTION_FROM_ROLE
42
+ }
43
+
44
+ /**
45
+ * @dev Encodes a single RBAC configuration action in a batch
46
+ */
47
+ struct RoleConfigAction {
48
+ RoleConfigActionType actionType;
49
+ bytes data;
50
+ }
51
+
52
+ /**
53
+ * @dev Unified event for all RBAC configuration changes applied via batches
54
+ *
55
+ * - actionType: the high-level type of configuration action
56
+ * - roleHash: affected role hash (if applicable, otherwise 0)
57
+ * - functionSelector: affected function selector (if applicable, otherwise 0)
58
+ * - data: optional action-specific payload (kept minimal for size; decoded off-chain if needed)
59
+ */
60
+ event RoleConfigApplied(
61
+ RoleConfigActionType indexed actionType,
62
+ bytes32 indexed roleHash,
63
+ bytes4 indexed functionSelector,
64
+ bytes data
65
+ );
66
+
67
+ /**
68
+ * @notice Initializer to initialize RuntimeRBAC
69
+ * @param initialOwner The initial owner address
70
+ * @param broadcaster The broadcaster address
71
+ * @param recovery The recovery address
72
+ * @param timeLockPeriodSec The timelock period in seconds
73
+ * @param eventForwarder The event forwarder address
74
+ */
75
+ function initialize(
76
+ address initialOwner,
77
+ address broadcaster,
78
+ address recovery,
79
+ uint256 timeLockPeriodSec,
80
+ address eventForwarder
81
+ ) public virtual onlyInitializing {
82
+ // Initialize base state machine (only if not already initialized)
83
+ if (!_secureState.initialized) {
84
+ _initializeBaseStateMachine(initialOwner, broadcaster, recovery, timeLockPeriodSec, eventForwarder);
85
+ }
86
+
87
+ // Load RuntimeRBAC-specific definitions
88
+ IDefinition.RolePermission memory permissions = RuntimeRBACDefinitions.getRolePermissions();
89
+ _loadDefinitions(
90
+ RuntimeRBACDefinitions.getFunctionSchemas(),
91
+ permissions.roleHashes,
92
+ permissions.functionPermissions
93
+ );
94
+ }
95
+
96
+ // ============ INTERFACE SUPPORT ============
97
+
98
+ /**
99
+ * @dev See {IERC165-supportsInterface}.
100
+ * @notice Adds IRuntimeRBAC interface ID for component detection
101
+ */
102
+ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
103
+ return interfaceId == type(IRuntimeRBAC).interfaceId || super.supportsInterface(interfaceId);
104
+ }
105
+
106
+ // ============ ROLE CONFIGURATION BATCH INTERFACE ============
107
+
108
+ /**
109
+ * @dev Creates execution params for a RBAC configuration batch
110
+ * @param actions Encoded role configuration actions
111
+ * @return The execution params for EngineBlox
112
+ */
113
+ function roleConfigBatchExecutionParams(
114
+ RoleConfigAction[] memory actions
115
+ ) public pure returns (bytes memory) {
116
+ return abi.encode(actions);
117
+ }
118
+
119
+ /**
120
+ * @dev Requests and approves a RBAC configuration batch using a meta-transaction
121
+ * @param metaTx The meta-transaction
122
+ * @return The transaction record
123
+ * @notice OWNER signs, BROADCASTER executes according to RuntimeRBACDefinitions
124
+ */
125
+ function roleConfigBatchRequestAndApprove(
126
+ EngineBlox.MetaTransaction memory metaTx
127
+ ) public returns (EngineBlox.TxRecord memory) {
128
+ _validateBroadcaster(msg.sender);
129
+ return _requestAndApproveTransaction(metaTx);
130
+ }
131
+
132
+ /**
133
+ * @dev External function that can only be called by the contract itself to execute a RBAC configuration batch
134
+ * @param actions Encoded role configuration actions
135
+ */
136
+ function executeRoleConfigBatch(RoleConfigAction[] calldata actions) external {
137
+ SharedValidation.validateInternalCall(address(this));
138
+ _executeRoleConfigBatch(actions);
139
+ }
140
+
141
+ // Essential Query Functions Only
142
+
143
+ /**
144
+ * @dev Gets function schema information
145
+ * @param functionSelector The function selector to get information for
146
+ * @return functionSignature The function signature or name
147
+ * @return functionSelectorReturn The function selector
148
+ * @return operationType The operation type
149
+ * @return operationName The operation name
150
+ * @return supportedActions The supported actions
151
+ * @return isProtected Whether the function schema is protected
152
+ */
153
+ function getFunctionSchema(bytes4 functionSelector) external view returns (
154
+ string memory functionSignature,
155
+ bytes4 functionSelectorReturn,
156
+ bytes32 operationType,
157
+ string memory operationName,
158
+ EngineBlox.TxAction[] memory supportedActions,
159
+ bool isProtected
160
+ ) {
161
+ EngineBlox.FunctionSchema storage schema = _getSecureState().functions[functionSelector];
162
+ if (schema.functionSelector != functionSelector) {
163
+ revert SharedValidation.ResourceNotFound(bytes32(functionSelector));
164
+ }
165
+
166
+ // Convert bitmap to array
167
+ supportedActions = _convertBitmapToActions(schema.supportedActionsBitmap);
168
+
169
+ return (
170
+ schema.functionSignature,
171
+ schema.functionSelector,
172
+ schema.operationType,
173
+ schema.operationName,
174
+ supportedActions,
175
+ schema.isProtected
176
+ );
177
+ }
178
+
179
+ /**
180
+ * @dev Gets all authorized wallets for a role
181
+ * @param roleHash The role hash to get wallets for
182
+ * @return Array of authorized wallet addresses
183
+ * @notice Requires caller to have any role (via _validateAnyRole) to limit information visibility
184
+ */
185
+ function getWalletsInRole(bytes32 roleHash) public view returns (address[] memory) {
186
+ _validateAnyRole();
187
+ _validateRoleExists(roleHash);
188
+
189
+ // Get role info to determine wallet count
190
+ EngineBlox.Role storage role = _getSecureState().getRole(roleHash);
191
+ uint256 walletCount = role.walletCount;
192
+
193
+ // Build array by iterating through wallets using _getAuthorizedWalletAt
194
+ address[] memory wallets = new address[](walletCount);
195
+ for (uint256 i = 0; i < walletCount; i++) {
196
+ wallets[i] = _getAuthorizedWalletAt(roleHash, i);
197
+ }
198
+
199
+ return wallets;
200
+ }
201
+
202
+ // ============ HELPER FUNCTIONS ============
203
+
204
+ /**
205
+ * @dev Internal helper to execute a RBAC configuration batch
206
+ * @param actions Encoded role configuration actions
207
+ */
208
+ function _executeRoleConfigBatch(RoleConfigAction[] calldata actions) internal {
209
+ // Validate batch size limit
210
+ SharedValidation.validateBatchSize(
211
+ actions.length,
212
+ EngineBlox.MAX_BATCH_SIZE
213
+ );
214
+
215
+ for (uint256 i = 0; i < actions.length; i++) {
216
+ RoleConfigAction calldata action = actions[i];
217
+
218
+ if (action.actionType == RoleConfigActionType.CREATE_ROLE) {
219
+ // Decode CREATE_ROLE action data
220
+ // Format: (string roleName, uint256 maxWallets, FunctionPermission[] functionPermissions)
221
+ // FunctionPermission is struct(bytes4 functionSelector, uint16 grantedActionsBitmap, bytes4 handlerForSelector)
222
+ // When encoding from JavaScript, it's encoded as tuple(bytes4,uint16,bytes4)[]
223
+ // Solidity can decode tuple[] directly into struct[] if the layout matches
224
+ (
225
+ string memory roleName,
226
+ uint256 maxWallets,
227
+ EngineBlox.FunctionPermission[] memory functionPermissions
228
+ ) = abi.decode(action.data, (string, uint256, EngineBlox.FunctionPermission[]));
229
+
230
+ bytes32 roleHash = _createNewRole(roleName, maxWallets, functionPermissions);
231
+
232
+ emit RoleConfigApplied(
233
+ RoleConfigActionType.CREATE_ROLE,
234
+ roleHash,
235
+ bytes4(0),
236
+ "" // optional: abi.encode(roleName, maxWallets)
237
+ );
238
+ } else if (action.actionType == RoleConfigActionType.REMOVE_ROLE) {
239
+ (bytes32 roleHash) = abi.decode(action.data, (bytes32));
240
+ _removeRole(roleHash);
241
+
242
+ emit RoleConfigApplied(
243
+ RoleConfigActionType.REMOVE_ROLE,
244
+ roleHash,
245
+ bytes4(0),
246
+ ""
247
+ );
248
+ } else if (action.actionType == RoleConfigActionType.ADD_WALLET) {
249
+ (bytes32 roleHash, address wallet) = abi.decode(action.data, (bytes32, address));
250
+
251
+ // Security check: Prevent editing protected roles
252
+ if (_getSecureState().roles[roleHash].isProtected) {
253
+ revert SharedValidation.CannotModifyProtected(roleHash);
254
+ }
255
+
256
+ _assignWallet(roleHash, wallet);
257
+
258
+ emit RoleConfigApplied(
259
+ RoleConfigActionType.ADD_WALLET,
260
+ roleHash,
261
+ bytes4(0),
262
+ "" // optional: abi.encode(wallet)
263
+ );
264
+ } else if (action.actionType == RoleConfigActionType.REVOKE_WALLET) {
265
+ (bytes32 roleHash, address wallet) = abi.decode(action.data, (bytes32, address));
266
+
267
+ // Security check: Prevent editing protected roles
268
+ if (_getSecureState().roles[roleHash].isProtected) {
269
+ revert SharedValidation.CannotModifyProtected(roleHash);
270
+ }
271
+
272
+ _revokeWallet(roleHash, wallet);
273
+
274
+ emit RoleConfigApplied(
275
+ RoleConfigActionType.REVOKE_WALLET,
276
+ roleHash,
277
+ bytes4(0),
278
+ "" // optional: abi.encode(wallet)
279
+ );
280
+ } else if (action.actionType == RoleConfigActionType.ADD_FUNCTION_TO_ROLE) {
281
+ (
282
+ bytes32 roleHash,
283
+ EngineBlox.FunctionPermission memory functionPermission
284
+ ) = abi.decode(action.data, (bytes32, EngineBlox.FunctionPermission));
285
+
286
+ _addFunctionToRole(roleHash, functionPermission);
287
+
288
+ emit RoleConfigApplied(
289
+ RoleConfigActionType.ADD_FUNCTION_TO_ROLE,
290
+ roleHash,
291
+ functionPermission.functionSelector,
292
+ ""
293
+ );
294
+ } else if (action.actionType == RoleConfigActionType.REMOVE_FUNCTION_FROM_ROLE) {
295
+ (bytes32 roleHash, bytes4 functionSelector) = abi.decode(action.data, (bytes32, bytes4));
296
+ _removeFunctionFromRole(roleHash, functionSelector);
297
+
298
+ emit RoleConfigApplied(
299
+ RoleConfigActionType.REMOVE_FUNCTION_FROM_ROLE,
300
+ roleHash,
301
+ functionSelector,
302
+ ""
303
+ );
304
+ } else {
305
+ revert SharedValidation.NotSupported();
306
+ }
307
+ }
308
+ }
309
+
310
+ // ============ INTERNAL ROLE / FUNCTION HELPERS ============
311
+
312
+ function _createNewRole(
313
+ string memory roleName,
314
+ uint256 maxWallets,
315
+ EngineBlox.FunctionPermission[] memory functionPermissions
316
+ ) internal returns (bytes32 roleHash) {
317
+ SharedValidation.validateRoleNameNotEmpty(roleName);
318
+ SharedValidation.validateMaxWalletsGreaterThanZero(maxWallets);
319
+
320
+ roleHash = keccak256(bytes(roleName));
321
+
322
+ // Create the role in the secure state with isProtected = false
323
+ _createRole(roleName, maxWallets, false);
324
+
325
+ // Add all function permissions to the role
326
+ // NOTE: Function schemas must be registered BEFORE adding permissions to roles
327
+ // This is the same pattern used in _loadDefinitions: schemas first, then permissions
328
+ // The function selectors in functionPermissions must exist in supportedFunctionsSet
329
+ // (they should be registered during initialize() via RuntimeRBACDefinitions)
330
+ //
331
+ // CRITICAL: The order matters - _loadDefinitions loads schemas FIRST, then permissions
332
+ // In _createNewRole, we assume schemas are already registered (from initialize)
333
+ // If schemas aren't registered, addFunctionToRole will revert with ResourceNotFound
334
+ for (uint256 i = 0; i < functionPermissions.length; i++) {
335
+ // Add function permission to role
336
+ // addFunctionToRole will check:
337
+ // 1. Role exists in supportedRolesSet (✅ just created)
338
+ // 2. Function selector exists in supportedFunctionsSet (must be registered during initialize)
339
+ // 3. Actions are supported by function schema (via _validateMetaTxPermissions)
340
+ _addFunctionToRole(roleHash, functionPermissions[i]);
341
+ }
342
+ }
343
+
344
+ }
@@ -0,0 +1,108 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ pragma solidity 0.8.33;
3
+
4
+ import "../../lib/EngineBlox.sol";
5
+
6
+ /**
7
+ * @title IRuntimeRBAC
8
+ * @dev Interface for Runtime Role-Based Access Control system
9
+ *
10
+ * This interface defines the functions for managing runtime roles through batch operations.
11
+ * All role management operations are performed via the batch interface for atomic execution.
12
+ *
13
+ * Key Features:
14
+ * - Batch-based role configuration (atomic operations)
15
+ * - Runtime function schema registration
16
+ * - Integration with EngineBlox for secure operations
17
+ * - Query functions for role and permission inspection
18
+ *
19
+ * Note: This contract inherits from BaseStateMachine which provides additional query functions
20
+ * such as getRole(), hasRole(), getActiveRolePermissions(), getSupportedRoles(), etc.
21
+ */
22
+ interface IRuntimeRBAC {
23
+ /**
24
+ * @dev Action types for batched RBAC configuration
25
+ */
26
+ enum RoleConfigActionType {
27
+ CREATE_ROLE,
28
+ REMOVE_ROLE,
29
+ ADD_WALLET,
30
+ REVOKE_WALLET,
31
+ REGISTER_FUNCTION,
32
+ UNREGISTER_FUNCTION,
33
+ ADD_FUNCTION_TO_ROLE,
34
+ REMOVE_FUNCTION_FROM_ROLE,
35
+ LOAD_DEFINITIONS
36
+ }
37
+
38
+ /**
39
+ * @dev Encodes a single RBAC configuration action in a batch
40
+ */
41
+ struct RoleConfigAction {
42
+ RoleConfigActionType actionType;
43
+ bytes data;
44
+ }
45
+
46
+ /**
47
+ * @dev Unified event for all RBAC configuration changes applied via batches
48
+ * @param actionType The type of configuration action
49
+ * @param roleHash Affected role hash (if applicable, otherwise 0)
50
+ * @param functionSelector Affected function selector (if applicable, otherwise 0)
51
+ * @param data Optional action-specific payload
52
+ */
53
+ event RoleConfigApplied(
54
+ RoleConfigActionType indexed actionType,
55
+ bytes32 indexed roleHash,
56
+ bytes4 indexed functionSelector,
57
+ bytes data
58
+ );
59
+
60
+ // ============ ROLE CONFIGURATION BATCH INTERFACE ============
61
+
62
+ /**
63
+ * @dev Creates execution params for a RBAC configuration batch
64
+ * @param actions Encoded role configuration actions
65
+ * @return The execution params for EngineBlox
66
+ */
67
+ function roleConfigBatchExecutionParams(
68
+ RoleConfigAction[] memory actions
69
+ ) external pure returns (bytes memory);
70
+
71
+ /**
72
+ * @dev Requests and approves a RBAC configuration batch using a meta-transaction
73
+ * @param metaTx The meta-transaction
74
+ * @return The transaction record
75
+ */
76
+ function roleConfigBatchRequestAndApprove(
77
+ EngineBlox.MetaTransaction memory metaTx
78
+ ) external returns (EngineBlox.TxRecord memory);
79
+
80
+ // ============ QUERY FUNCTIONS ============
81
+
82
+ /**
83
+ * @dev Gets function schema information
84
+ * @param functionSelector The function selector to get information for
85
+ * @return functionSignature The function signature or name
86
+ * @return functionSelectorReturn The function selector
87
+ * @return operationType The operation type
88
+ * @return operationName The operation name
89
+ * @return supportedActions The supported actions
90
+ * @return isProtected Whether the function schema is protected
91
+ */
92
+ function getFunctionSchema(bytes4 functionSelector) external view returns (
93
+ string memory functionSignature,
94
+ bytes4 functionSelectorReturn,
95
+ bytes32 operationType,
96
+ string memory operationName,
97
+ EngineBlox.TxAction[] memory supportedActions,
98
+ bool isProtected
99
+ );
100
+
101
+ /**
102
+ * @dev Gets all authorized wallets for a role
103
+ * @param roleHash The role hash to get wallets for
104
+ * @return Array of authorized wallet addresses
105
+ * @notice Requires caller to have any role (via _validateAnyRole) for privacy protection
106
+ */
107
+ function getWalletsInRole(bytes32 roleHash) external view returns (address[] memory);
108
+ }