SDK Extensions Development
Guidance for SDK Extension Developers
If you are creating new extensions:
- Inherit first from
BaseMiddleware
(which also serves asBaseExtension
) to gain access to internal VaultManager, OperatorManager, AccessManager, and KeyManager functions, or from one of the extendable managers such asKeyManager
,CaptureTimestampManager
,AccessManager
, orStakePowerManager
. - Follow ERC-7201 storage standards to avoid storage collisions.
- Include a
uint64 public constant {YourExtensionName}_VERSION = 1;
variable for off-chain detection and indexing by dashboards. - If your extension needs initialization, write
__{ExtensionName}_init
and useonlyInitializing
. - Try to avoid signature collisions with other extensions. If possible, consider how your extension might integrate with or complement existing ones.
- Provide hooks for customization in your extension. This allows middleware developers to add or replace logic as needed.
contract MyExtension is BaseMiddleware, SomeExtension {
uint64 public constant MY_EXTENSION_VERSION = 1;
struct MyExtensionStorage {
...
}
// keccak256(abi.encode(uint256(keccak256("symbiotic.storage.MyExtension")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant MyExtensionStorageLocation =
0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef;
function _getMyExtensionStorage() internal pure returns (MyExtensionStorage storage $) {
bytes32 location = MyExtensionStorageLocation;
assembly {
$.slot := location
}
}
function __MyExtension_init() internal onlyInitializing {
...
}
function doSomething() external {
_beforeDoSomething();
_someBaseMiddlewareInternalFunction();
...
}
function _beforeDoSomething() internal virtual {
...
}
}