ERC721: Keep track of holder addresses and tokenIds by address

Hi!

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)
    public
    view
    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 !