contract Whitelist is Ownable {
    struct WalletInfo {
        string data;
        bool whitelisted;
        uint256 createdTimestamp;
    }

    address private addressApi;

    mapping(address => WalletInfo) public whitelist;

    uint256 public whitelistLength = 0;

    modifier onlyPrivilegeAddresses {
        require(msg.sender == addressApi || msg.sender == owner);
        _;
    }

    /**
    * @dev Set backend Api address.
    * @dev Accept request from owner only.
    * @param _api The address of backend API.
    */
    function setApiAddress(address _api) onlyOwner public {
        require(_api != address(0));

        addressApi = _api;
    }

    /**
    * @dev Add wallet to whitelist.
    * @dev Accept request from privilege adresses only.
    * @param _wallet The address of wallet to add.
    * @param _data The checksum of additional wallet data.
    */  
    function addWallet(address _wallet, string _data) onlyPrivilegeAddresses public {
        require(_wallet != address(0));
        require(!isWhitelisted(_wallet));
        whitelist[_wallet].data = _data;
        whitelist[_wallet].whitelisted = true;
        whitelist[_wallet].createdTimestamp = now;
        whitelistLength++;
    }

    /**
    * @dev Update additional data for whitelisted wallet.
    * @dev Accept request from privilege adresses only.
    * @param _wallet The address of whitelisted wallet to update.
    * @param _data The checksum of new additional wallet data.
    */      
    function updateWallet(address _wallet, string _data) onlyPrivilegeAddresses public {
        require(_wallet != address(0));
        require(isWhitelisted(_wallet));
        whitelist[_wallet].data = _data;
    }

    /**
    * @dev Remove wallet from whitelist.
    * @dev Accept request from privilege adresses only.
    * @param _wallet The address of whitelisted wallet to remove.
    */  
    function removeWallet(address _wallet) onlyPrivilegeAddresses public {
        require(_wallet != address(0));
        require(isWhitelisted(_wallet));
        delete whitelist[_wallet];
        whitelistLength--;
    }

    /**
    * @dev Check the specified wallet whether it is in the whitelist.
    * @param _wallet The address of wallet to check.
    */ 
    function isWhitelisted(address _wallet) constant public returns (bool) {
        return whitelist[_wallet].whitelisted;
    }

    /**
    * @dev Get the checksum of additional data for the specified whitelisted wallet.
    * @param _wallet The address of wallet to get.
    */ 
    function walletData(address _wallet) constant public returns (string) {
        return whitelist[_wallet].data;
    }

    /**
    * @dev Get the creation timestamp for the specified whitelisted wallet.
    * @param _wallet The address of wallet to get.
    */
    function walletCreatedTimestamp(address _wallet) constant public returns (uint256) {
        return whitelist[_wallet].createdTimestamp;
    }
}
/**
 * @title Whitelist contract
 * @dev Whitelist for wallets, with additional data for every wallet.
 */
function walletData(address _wallet) constant public returns (string) {
    return whitelist[_wallet].data;
}

/**
 * @dev Get the checksum of additional data for the specified whitelisted wallet.
 * @param _wallet The address of wallet to get.
 */