A library for linked lists in Solidity
The library comes with linked lists in different flavors:
- SentinelList: A linked list for addresses
- SentinelList4337: An ERC-4337 compliant linked list for addresses
- SentinelListBytes32: A linked list for bytes32
In a contract, you can use the SentinelList library to store a linked list of addresses:
import {SentinelListLib} from "sentinellist/SentinelList.sol";
contract Example {
using SentinelListLib for SentinelListLib.SentinelList;
// Declare a variable to store the data
// Note: this can also be in a mapping or other data structure
SentinelListLib.SentinelList list;
function set(address newAddress) external {
// Store the data
list.push(newAddress);
}
function get(uint256 size) external view returns (address[] memory addressArray) {
// Retrieve the data
(addressArray,) = list.getEntriesPaginated(SENTINEL, size);
}
}init(SentinelList storage self): Initialize the list (required before using the list and will revert if the list is already initialized)alreadyInitialized(SentinelList storage self): Check if the list is already initializedgetNext(SentinelList storage self, address entry): Get the next entry in the listpush(SentinelList storage self, address newEntry): Add a new entry to the listpop(SentinelList storage self, address prevEntry, address popEntry): Remove an entry from the listpopAll(SentinelList storage self): Remove all entries from the listcontains(SentinelList storage self, address entry): Check if an entry is in the listgetEntriesPaginated(SentinelList storage self, address start, uint256 size): Get a paginated list of entries fromstartwith a maximum ofsizeentries
init(SentinelList storage self, address account): Initialize the list (required before using the list and will revert if the list is already initialized)alreadyInitialized(SentinelList storage self, address account): Check if the list is already initializedgetNext(SentinelList storage self, address account, address entry): Get the next entry in the listpush(SentinelList storage self, address account, address newEntry): Add a new entry to the listpop(SentinelList storage self, address account, address prevEntry, address popEntry): Remove an entry from the listpopAll(SentinelList storage self, address account): Remove all entries from the listcontains(SentinelList storage self, address account, address entry): Check if an entry is in the listgetEntriesPaginated(SentinelList storage self, address account, address start, uint256 size): Get a paginated list of entries fromstartwith a maximum ofsizeentries
init(LinkedBytes32 storage self): Initialize the list (required before using the list and will revert if the list is already initialized)alreadyInitialized(LinkedBytes32 storage self): Check if the list is already initializedgetNext(LinkedBytes32 storage self, bytes32 entry): Get the next entry in the listpush(LinkedBytes32 storage self, bytes32 newEntry): Add a new entry to the listpop(LinkedBytes32 storage self, bytes32 prevEntry, bytes32 popEntry): Remove an entry from the listpopAll(LinkedBytes32 storage self): Remove all entries from the listcontains(LinkedBytes32 storage self, bytes32 entry): Check if an entry is in the listgetEntriesPaginated(LinkedBytes32 storage self, bytes32 start, uint256 size): Get a paginated list of entries fromstartwith a maximum ofsizeentries
To install the dependencies, run:
forge installTo build the project, run:
forge buildTo run the tests, run:
forge testFor feature or change requests, feel free to open a PR, start a discussion or get in touch with us.