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 storage wallet = walletsIDMap[recipientExternalID];
        require(wallet.walletAddress == address(0x0), "WalletFactory: cannot associate same recipientExternalID twice.");

        MBDAWallet newWallet = new MBDAWallet(
            _controller,
            recipientExternalID
        );

        wallet.walletAddress = address(newWallet);
        wallet.controller = _controller;
        wallet.recipientID = recipientExternalID;

        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 CreateWallet(
        address _controller,
        string memory recipientExternalID
    ) public returns (bool) {
        Wallet storage wallet = walletsIDMap[recipientExternalID];
        require(wallet.walletAddress == address(0x0), "WalletFactory: cannot associate same recipientExternalID twice.");

        MBDAWallet newWallet = new MBDAWallet(
            _controller,
            recipientExternalID
        );

        wallet.walletAddress = address(newWallet);
        wallet.controller = _controller;
        wallet.recipientID = recipientExternalID;

        wallets.push(wallet);
        walletsIDMap[recipientExternalID] = wallet;

        emit NewWalletCreated(
            address(newWallet),
            _controller,
            recipientExternalID
        );

        return true;
    }
/**
 * @dev Creates a new wallet
 * @param _controller - Controller of the new wallet
 * @param recipientExternalID - The Recipient ID (managed externally)
 * @return true if success
 */