ERC721: Keep track of holder addresses and tokenIds by address


Do you know an NFT contract which keeps track of holder addresses ?

Let's say I create an NFT contract, and 45 people mint my NFT, I want a function in my contract which returns these 45 addresses.

Something like this

function owners() public view returns (address[] memory) {
        address[] memory allOwners = new address[](totalSupply());

        for (uint256 i=1; i <= totalSupply(); i++) {

            address owner = ownerOf(i);
            allOwners[i] = owner;

        return allOwners;

I'm pretty sure someone already did it using OpenZeppelin ERC721Enumerable, but I can't find any examples

My guess is I need to use a transfer hook in _beforeTokenTransfer but I can't get it to work

I also want to know what are the tokenIds hold by an address
Lets say 0x123 holds the 1st, 2nd, 3rd NFT, and 0x888 holds the 4th and 5th

I want to have [1,2,3] with 0x123 as input, [4,5] with 0x888 as input, and with 0x555 as input

I came up with this design, can someone confirms me that this is correct ?

  function walletOfOwner(address owner)
    returns (uint256[] memory)
    uint256 ownerTokenCount = balanceOf(owner);
    uint256[] memory tokenIds = new uint256[](ownerTokenCount);
    for (uint256 i; i < ownerTokenCount; i++) {
      tokenIds[i] = tokenOfOwnerByIndex(owner, i);
    return tokenIds;

Thanks !