contract MBDAWalletFactory {
    struct Wallet {
        string recipientID;
        address walletAddress;
        address controller;
    }

    Wallet[] public wallets;
    mapping(string => Wallet) public walletsIDMap;

    event NewWalletCreated(
        address walletAddress,
        address indexed controller,
        string recipientExternalID
    );

    /**
     * @dev Creates a new wallet
     * @param _controller - Controller of the new wallet
     * @param recipientExternalID - The Recipient ID (managed externally)
     * @return true if success
     */
    function CreateWallet(
        address _controller,
        string memory recipientExternalID
    ) public returns (bool) {
        Wallet memory wallet = walletsIDMap[recipientExternalID];
        if (wallet.walletAddress != address(0x0)) {
            return false;
        }
        MBDAWallet newWallet = (new MBDAWallet)(
            _controller,
            recipientExternalID
        );
        wallet = Wallet(recipientExternalID, address(newWallet), _controller);
        wallets.push(wallet);
        walletsIDMap[recipientExternalID] = wallet;
        emit NewWalletCreated(
            address(newWallet),
            _controller,
            recipientExternalID
        );
        return true;
    }

    /**
     * @dev Total Wallets ever created
     * @return the total wallets ever created
     */
    function getTotalWalletsCreated() public view returns (uint256) {
        return wallets.length;
    }

    /**
     * @dev Wallet getter
     * @param recipientID recipient ID
     * @return Wallet (for frontend use)
     */
    function getWallet(string calldata recipientID)
        external
        view
        returns (Wallet memory)
    {
        require(
            walletsIDMap[recipientID].walletAddress != address(0x0),
            "invalid wallet"
        );
        return walletsIDMap[recipientID];
    }
}
/**
 * @dev Wallet Factory
 */
function getWallet(string calldata recipientID)
    external
    view
    returns (Wallet memory)
{
    require(
        walletsIDMap[recipientID].walletAddress != address(0x0),
        "invalid wallet"
    );
    return walletsIDMap[recipientID];
}

/**
 * @dev Wallet getter
 * @param recipientID recipient ID
 * @return Wallet (for frontend use)
 */