> For the complete documentation index, see [llms.txt](https://calnix.gitbook.io/eth-dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://calnix.gitbook.io/eth-dev/solidity-patterns/claimdelegate-stack-unique-owners.md).

# claimDelegate: stack unique owners

* for some array of tokenIds: \[0,1,2,3,...]
* the owners array, could contain repeated owners: \[userA, userB, userA, userA]
* this collapses the owner array to unique owners, and calculates their total claimable amount to be transferred out
* the uniqueArrays have the same length of the original arrays -- they have trailing 0s to fill up the replaced elements

```solidity
    /**
     * @notice Users to claim via delegated hot wallets
     * @dev msg.sender is designated delegate of nfts
     * @param tokenIds Nfts' tokenId
     */  
    function claimDelegated(uint256[] calldata tokenIds) external whenStartedAndBeforeDeadline whenNotPaused {
        
        // array validation
        uint256 tokenIdsLength = tokenIds.length;
        if(tokenIdsLength == 0) revert EmptyArray(); 

        // check delegation on msg.sender
        bytes[] memory data = new bytes[](tokenIdsLength);
        address[] memory owners = new address[](tokenIdsLength);
        for (uint256 i = 0; i < tokenIdsLength; ++i) {
            
            uint256 tokenId = tokenIds[i];

            // get and store nft Owner
            address nftOwner = NFT.ownerOf(tokenId);          
            owners[i] = nftOwner;

            // data for multicall
            data[i] = abi.encodeCall(IDelegateRegistry(DELEGATE_REGISTRY).checkDelegateForERC721, 
                        (msg.sender, nftOwner, address(NFT), tokenId, ""));
        }
        
        // data for staticCall
        bytes memory staticData = abi.encodeCall(IDelegateRegistry(DELEGATE_REGISTRY).multicall, data); 
        
        // staticCall
        (bool success, bytes memory result) = DELEGATE_REGISTRY.staticcall(staticData); 
        if (!success) revert StaticCallFailed();

        // if a tokenId is not delegated will return false; as a bool
        bytes[] memory results = abi.decode(result, (bytes[]));


        //note: ending w/ 0s as placeholder
        address[] memory uniqueOwners = new address[](tokenIdsLength);
        uint256[] memory uniqueAmounts = new uint256[](tokenIdsLength);

        uint256 totalAmount;
        uint256 uniqueCounter;

        for (uint256 i = 0; i < tokenIdsLength; ++i) {
            
            // multiCall uses delegateCall: decode return data
            bool isDelegated = abi.decode(results[i], (bool));
            if(!isDelegated) revert InvalidDelegate();

            // update tokenId: storage is updated
            uint256 tokenId = tokenIds[i];
            uint256 claimable = _updateLastClaimed(tokenId);
            
            totalAmount += claimable;

            address owner = owners[i];
            
            // populate 1st element
            if(i == 0) {
                
                uniqueOwners[i] = owner;
                uniqueAmounts[i] = claimable;

                ++uniqueCounter;

            } else {    
                
                // check all prev.| reverse loop decrement to 0
                for (uint256 j = i-1; j >= 0; j--) {
                    
                    // check if match w/ any of the previous owners
                    if (owner == uniqueOwners[j]) {

                        uniqueAmounts[j] += claimable;
                        break;
                    }
                    
                    // If we've reached the beginning and found no match
                    if (j == 0) {
                        
                        // add to array
                        uniqueOwners[i] = owner;
                        uniqueAmounts[i] = claimable;

                        ++uniqueCounter;
                    }
                }

            }
        }
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://calnix.gitbook.io/eth-dev/solidity-patterns/claimdelegate-stack-unique-owners.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
