# Whitelisted Redemption

### Whitelisted Package Redemption

`WhitelistPackageRedemption` provides a simple example of how users can create and redeem packages using the PostOffice contract while enforcing a whitelist requirement for package redemption.

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import "./PostOffice.sol";

contract WhitelistPackageRedemption {
    PostOffice public postOffice;
    mapping(address => bool) public whitelist;

    constructor(address _postOfficeAddress) {
        postOffice = PostOffice(_postOfficeAddress);
        // Add addresses to the whitelist
        whitelist[address(0x123)] = true;
        whitelist[address(0x456)] = true;
        whitelist[address(0x789)] = true;
        whitelist[address(0xABC)] = true;
        whitelist[address(0xDEF)] = true;
    }

    function shipPackage(
        CapsuleData.CapsuleContent calldata packageContent_,
        PostOffice.SecurityInfo calldata securityInfo_,
        address receiver_
    ) external returns (uint256) {
        return postOffice.shipPackage(packageContent_, securityInfo_, receiver_);
    }

    function pickupPackage(
        uint256 packageId_,
        bytes32 messageHash,
        bytes[] calldata signature_,
        string calldata rawPassword_,
        string calldata salt_,
        bool shouldRedeem_
    ) external {
        uint256 _len = signature_.length;
        require(_len == 5, "Invalid number of signatures");

        // Verify signatures from whitelisted addresses
        for (uint256 i = 0; i < _len; i++) {
            address _signer = verifySignature(messageHash, signature_[i]);
            require(whitelist[_signer], "Invalid signer");
        }
        postOffice.pickup(packageId_, rawPassword_, salt_, shouldRedeem_);
    }

    function verifySignature(bytes32 messageHash_, bytes memory signature_) internal pure returns (address) {
        bytes32 r;
        bytes32 s;
        uint8 v;

        // Split the signature into r, s, and v components
        assembly {
            r := mload(add(signature_, 32))
            s := mload(add(signature_, 64))
            v := byte(0, mload(add(signature_, 96)))
        }
        // Verify and recover the signer's address
        return ecrecover(messageHash_, v, r, s);
    }
}
```

In this contract, users can create packages by calling the `createPackage` function, providing the necessary parameters such as the package manager, receiver, password hash, and asset key. The function will invoke the `shipPackage` method from the PostOffice contract to create the package.

To redeem a package, users need to call the `redeemPackage` function with the package ID, message hash, and an array of signatures. The function will verify the signatures from the whitelisted addresses by calling the `verifySignature` function, and if all signatures are valid, it will invoke the `redeemPackage` method from the PostOffice contract.


---

# Agent Instructions: 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://docs.capsulelabs.xyz/protocol-overview/developer-walkthroughs/code-examples/whitelisted-redemption.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.
