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.

// 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.

Last updated